[java] How to fix the Hibernate "object references an unsaved transient instance - save the transient instance before flushing" error

Introduction

When using JPA and Hibernate, an entity can be in one of the following 4 states:

  • New - A newly created object that hasn’t ever been associated with a Hibernate Session (a.k.a Persistence Context) and is not mapped to any database table row is considered to be in the New or Transient state.

To become persisted we need to either explicitly call the persist method or make use of the transitive persistence mechanism.

  • Persistent - A persistent entity has been associated with a database table row and it’s being managed by the currently running Persistence Context.

Any change made to such an entity is going to be detected and propagated to the database (during the Session flush-time).

  • Detached - Once the currently running Persistence Context is closed all the previously managed entities become detached. Successive changes will no longer be tracked and no automatic database synchronization is going to happen.

  • Removed - Although JPA demands that managed entities only are allowed to be removed, Hibernate can also delete detached entities (but only through a remove method call).

Entity state transitions

To move an entity from one state to the other, you can use the persist, remove or merge methods.

JPA entity states

Fixing the problem

The issue you are describing in your question:

object references an unsaved transient instance - save the transient instance before flushing

is caused by associating an entity in the state of New to an entity that's in the state of Managed.

This can happen when you are associating a child entity to a one-to-many collection in the parent entity, and the collection does not cascade the entity state transitions.

So, you can fix this by adding cascade to the entity association that triggered this failure, as follows:

The @OneToOne association

@OneToOne(
    mappedBy = "post",
    orphanRemoval = true,
    cascade = CascadeType.ALL)
private PostDetails details;

Notice the CascadeType.ALL value we added for the cascade attribute.

The @OneToMany association

@OneToMany(
    mappedBy = "post", 
    orphanRemoval = true,
    cascade = CascadeType.ALL)
private List<Comment> comments = new ArrayList<>();

Again, the CascadeType.ALL is suitable for the bidirectional @OneToMany associations.

Now, in order for the cascade to work properly in a bidirectional, you also need to make sure that the parent and child associations are in sync.

The @ManyToMany association

@ManyToMany(
    mappedBy = "authors",
    cascade = {
        CascadeType.PERSIST, 
        CascadeType.MERGE
    }
)
private List<Book> books = new ArrayList<>();

In a @ManyToMany association, you cannot use CascadeType.ALL or orphanRemoval as this will propagate the delete entity state transition from one parent to another parent entity.

Therefore, for @ManyToMany associations, you usually cascade the CascadeType.PERSIST or CascadeType.MERGE operations. Alternatively, you can expand that to DETACH or REFRESH.

Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to hibernate

Hibernate Error executing DDL via JDBC Statement How does spring.jpa.hibernate.ddl-auto property exactly work in Spring? Error creating bean with name 'entityManagerFactory' defined in class path resource : Invocation of init method failed JPA Hibernate Persistence exception [PersistenceUnit: default] Unable to build Hibernate SessionFactory Disable all Database related auto configuration in Spring Boot Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] HikariCP - connection is not available Hibernate-sequence doesn't exist How to find distinct rows with field in list using JPA and Spring? Spring Data JPA and Exists query

Examples related to jpa

No converter found capable of converting from type to type How does spring.jpa.hibernate.ddl-auto property exactly work in Spring? Deserialize Java 8 LocalDateTime with JacksonMapper Error creating bean with name 'entityManagerFactory' defined in class path resource : Invocation of init method failed How to beautifully update a JPA entity in Spring Data? JPA Hibernate Persistence exception [PersistenceUnit: default] Unable to build Hibernate SessionFactory How to return a custom object from a Spring Data JPA GROUP BY query How to find distinct rows with field in list using JPA and Spring? What is this spring.jpa.open-in-view=true property in Spring Boot? Spring Data JPA and Exists query

Examples related to orm

How to select specific columns in laravel eloquent Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] How to query between two dates using Laravel and Eloquent? Laravel - Eloquent "Has", "With", "WhereHas" - What do they mean? How to Make Laravel Eloquent "IN" Query? How to auto generate migrations with Sequelize CLI from Sequelize models? How to fix org.hibernate.LazyInitializationException - could not initialize proxy - no Session Select the first 10 rows - Laravel Eloquent How to make join queries using Sequelize on Node.js What is Persistence Context?

Examples related to entity

org.hibernate.MappingException: Unknown entity: annotations.Users PersistentObjectException: detached entity passed to persist thrown by JPA and Hibernate Improving bulk insert performance in Entity framework What is the difference between persist() and merge() in JPA and Hibernate? How to update only one field using Entity Framework? How to set a default entity property value with Hibernate How to delete an object by id with entity framework How to fix the Hibernate "object references an unsaved transient instance - save the transient instance before flushing" error