el objeto hace referencia a una instancia transitoria no guardada: guarde la instancia transitoria antes de enjuagar

Recibo el siguiente error cuando guardo el objeto usando Hibernate

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

Debe incluir cascade="all" (si usa xml) o cascade=CascadeType.ALL (si usa anotaciones) en su mapeo de colección.

Esto sucede porque tiene una colección en su entidad, y esa colección tiene uno o más elementos que no están presentes en la base de datos. Al especificar las opciones anteriores, le indica a hibernate que las guarde en la base de datos al guardar su elemento primario.

Creo que esto podría ser solo una respuesta repetida, pero solo para aclarar, obtuve esto en un mapeo @OneToOne así como en @OneToMany . En ambos casos, fue el hecho de que el objeto Child que estaba agregando al Parent no se guardó aún en la base de datos. Entonces, cuando agregué el elemento Child al elemento Parent y luego guardé el documento principal, Hibernate arrojó el mensaje "object references an unsaved transient instance - save the transient instance before flushing" guardada "object references an unsaved transient instance - save the transient instance before flushing" mensaje al guardar el elemento principal.

Al agregar la cascade = {CascadeType.ALL} en la referencia Parent's al Child resolvió el problema en ambos casos. Esto salvó al Child y al Parent .

Lo siento por cualquier respuesta repetida, solo quería aclarar más para la gente.

 @OneToOne(cascade = {CascadeType.ALL}) @JoinColumn(name = "performancelog_id") public PerformanceLog getPerformanceLog() { return performanceLog; } 

Esto ocurre cuando se guarda un objeto cuando Hibernate piensa que necesita guardar un objeto que está asociado con el que está guardando.

Tuve este problema y no quería guardar los cambios en el objeto referenciado, así que quería que el tipo de cascada fuera NINGUNO.

El truco consiste en garantizar que el ID y la VERSIÓN en el objeto al que se hace referencia se configuren para que Hibernate no piense que el objeto al que se hace referencia es un objeto nuevo que necesita guardarse. Esto funcionó para mí.

Examine todas las relaciones de la clase que está guardando para calcular los objetos asociados (y los objetos asociados de los objetos asociados) y asegúrese de que el ID y la VERSIÓN estén configurados en todos los objetos del árbol de objetos.

O, si desea utilizar “poderes” mínimos (por ejemplo, si no desea una eliminación en cascada) para lograr lo que desea, utilice

 import org.hibernate.annotations.Cascade; import org.hibernate.annotations.CascadeType; ... @Cascade({CascadeType.SAVE_UPDATE}) private Set children; 

En mi caso, fue causado por no tener CascadeType en el lado @ManyToOne de la relación bidireccional. Para ser más precisos, tenía CascadeType.ALL en @OneToMany side y no lo tenía en @ManyToOne . Agregar CascadeType.ALL a @ManyToOne resolvió el problema. Lado uno a muchos :

 @OneToMany(cascade = CascadeType.ALL, mappedBy="globalConfig", orphanRemoval = true) private SetgcScopeSet; 

De muchos lados (causó el problema)

 @ManyToOne @JoinColumn(name="global_config_id") private GlobalConfig globalConfig; 

Muchos-a-uno (arreglado agregando CascadeType.PERSIST )

 @ManyToOne(cascade = CascadeType.PERSIST) @JoinColumn(name="global_config_id") private GlobalConfig globalConfig; 

Esto ocurrió para mí cuando persistió una entidad en la que el registro existente en la base de datos tenía un valor NULL para el campo anotado con @Version (para el locking optimista). Actualizar el valor NULL a 0 en la base de datos corrigió esto.

Esta no es la única razón del error. Lo encontré hace un momento por un error tipográfico en mi encoding, que creo que establece el valor de una entidad que ya se guardó.

 X x2 = new X(); x.setXid(memberid); // Error happened here - x was a previous global entity I created earlier Y.setX(x2); 

Descubrí el error al encontrar exactamente qué variable causó el error (en este caso String xid ). Utilicé una catch alrededor de todo el bloque de código que salvó a la entidad e imprimió los rastros.

 { code block that performed the operation } catch (Exception e) { e.printStackTrace(); // put a break-point here and inspect the 'e' return ERROR; } 

Si su colección es object.SetYouColection(null); intente: object.SetYouColection(null);

No use Cascade.All hasta que realmente tenga que hacerlo. Role y el Permission tienen una relación bidireccional de manyToMany . Entonces el siguiente código funcionaría bien

  Permission p = new Permission(); p.setName("help"); Permission p2 = new Permission(); p2.setName("self_info"); p = (Permission)crudRepository.save(p); // returned p has id filled in. p2 = (Permission)crudRepository.save(p2); // so does p2. Role role = new Role(); role.setAvailable(true); role.setDescription("a test role"); role.setRole("admin"); List pList = new ArrayList(); pList.add(p); pList.add(p2); role.setPermissions(pList); crudRepository.save(role); 

mientras que si el objeto es simplemente uno “nuevo”, arrojaría el mismo error.

Para agregar mis 2 centavos, recibí el mismo problema cuando accidentalmente envío null como identificación. El siguiente código muestra mi escenario (y OP no mencionó ningún escenario específico) .

 Employee emp = new Employee(); emp.setDept(new Dept(deptId)); // --> when deptId PKID is null, same error will be thrown // calls to other setters... em.persist(emp); 

Aquí estoy configurando el ID del departamento existente en una nueva instancia de empleado sin obtener primero la entidad de departamento, ya que no quiero que se active otra consulta de selección.

En algunos escenarios, deptId PKID viene como null desde el método de llamada y estoy obteniendo el mismo error.

Por lo tanto, tenga cuidado con null valores null para PK ID

me sale este error cuando uso

 getSession().save(object) 

pero funciona sin problemas cuando uso

 getSession().saveOrUpdate(object) 

además de todas las otras respuestas correctas, esto podría suceder si usa merge para persistir un objeto y accidentalmente olvida usar la referencia fusionada del objeto en la clase padre. considera el siguiente ejemplo

 merge(A); B.setA(A); persist(B); 

En este caso, fusiona A pero olvida usar el objeto fusionado de A para resolver el problema debes reescribir el código de esta manera.

 A=merge(A);//difference is here B.setA(A); persist(B); 

Otra razón posible: en mi caso, estaba intentando salvar al niño antes de salvar al padre, en una nueva entidad.

El código era algo así en un modelo User.java:

 this.lastName = lastName; this.isAdmin = isAdmin; this.accountStatus = "Active"; this.setNewPassword(password); this.timeJoin = new Date(); create(); 

El método setNewPassword () crea un registro PasswordHistory y lo agrega a la colección de historial en User. Como la statement create () aún no se había ejecutado para el padre, estaba intentando guardar en una colección de una entidad que aún no se había creado. Todo lo que tuve que hacer para solucionarlo fue mover la llamada a setNewPassword () después de la llamada a create ().

 this.lastName = lastName; this.isAdmin = isAdmin; this.accountStatus = "Active"; this.timeJoin = new Date(); create(); this.setNewPassword(password); 

Existe otra posibilidad que puede causar este error en hibernación. Puede establecer una referencia no guardada de su objeto A en una entidad adjunta B y desea persistir en el objeto C Incluso en este caso, obtendrá el error mencionado anteriormente.

Si está utilizando Spring Data JPA, entonces @Transactional anotación @Transactional a su implementación del servicio resolvería el problema.

En aras de la exhaustividad: A

 org.hibernate.TransientPropertyValueException 

con mensaje

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

también ocurrirá cuando intentes persistir / fusionar una entidad con una referencia a otra entidad que esté desapegada .

También enfrenté la misma situación. Al establecer la siguiente anotación encima de la propiedad, se solucionó la excepción solicitada.

La excepción que enfrenté.

 Exception in thread "main" java.lang.IllegalStateException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.model.Car_OneToMany 

Para superar, la anotación que utilicé.

  @OneToMany(cascade = {CascadeType.ALL}) @Column(name = "ListOfCarsDrivenByDriver") private List listOfCarsBeingDriven = new ArrayList(); 

Lo que hizo que Hibernate lanzara la excepción:

Esta excepción se genera en su consola porque el objeto secundario que adjunto al objeto principal no está presente en la base de datos en ese momento.

Al proporcionar @OneToMany(cascade = {CascadeType.ALL}) , le dice a Hibernate que los guarde en la base de datos mientras guarda el objeto principal.

Una forma simple de resolver este problema es salvar ambas entidades. primero guarde la entidad hijo y luego guarde la entidad padre. Debido a que la entidad padre depende de la entidad hijo para el valor de la clave externa.

Debajo del simple examen de la relación uno a uno

 insert into Department (name, numOfemp, Depno) values (?, ?, ?) Hibernate: insert into Employee (SSN, dep_Depno, firstName, lastName, middleName, empno) values (?, ?, ?, ?, ?, ?) Session session=sf.openSession(); session.beginTransaction(); session.save(dep); session.save(emp); 

Una posible causa del error es la inexistencia de la configuración del valor de la entidad principal; por ejemplo, para una relación departamento-empleados, debe escribir esto para corregir el error:

 Department dept = (Department)session.load(Department.class, dept_code); // dept_code is from the jsp form which you get in the controller with @RequestParam String department employee.setDepartment(dept); 

Hay tantas posibilidades de este error que otras posibilidades también están en agregar página o editar página. En mi caso, estaba intentando guardar un objeto AdvanceSalary. El problema es que al editar el empleado AdvanceSalary.employee_id es nulo porque en la edición no se configuró el employee.employee_id. He hecho un campo oculto y lo configuré. mi código funciona absolutamente bien.

  @Entity(name = "ic_advance_salary") @Table(name = "ic_advance_salary") public class AdvanceSalary extends BaseDO{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private Integer id; @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "employee_id", nullable = false) private Employee employee; @Column(name = "employee_id", insertable=false, updatable=false) @NotNull(message="Please enter employee Id") private Long employee_id; @Column(name = "advance_date") @DateTimeFormat(pattern = "dd-MMM-yyyy") @NotNull(message="Please enter advance date") private Date advance_date; @Column(name = "amount") @NotNull(message="Please enter Paid Amount") private Double amount; @Column(name = "cheque_date") @DateTimeFormat(pattern = "dd-MMM-yyyy") private Date cheque_date; @Column(name = "cheque_no") private String cheque_no; @Column(name = "remarks") private String remarks; public AdvanceSalary() { } public AdvanceSalary(Integer advance_salary_id) { this.id = advance_salary_id; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Employee getEmployee() { return employee; } public void setEmployee(Employee employee) { this.employee = employee; } public Long getEmployee_id() { return employee_id; } public void setEmployee_id(Long employee_id) { this.employee_id = employee_id; } } 

Me enfrenté a esta excepción cuando no persistí el objeto principal pero estaba salvando al niño. Para resolver el problema, en la misma sesión persistí tanto en los objetos secundarios como secundarios y usé CascadeType.ALL en el elemento primario.

Creo que se debe a que ha intentado persistir un objeto que tiene una referencia a otro objeto que aún no se ha conservado, por lo que prueba en el “lado DB” para poner una referencia a una fila que no existe

Caso 1: obtenía esta excepción cuando intentaba crear un elemento primario y guardar esa referencia principal para su hijo y luego otra consulta DELETE / UPDATE (JPQL). Así que simplemente descargué () la entidad recién creada después de crear el elemento primario y después de crear el elemento secundario utilizando la misma referencia principal. Funcionó para mí.

Caso 2

Clase de padres

 public class Reference implements Serializable { @Id @Column(precision=20, scale=0) private BigInteger id; @Temporal(TemporalType.TIMESTAMP) private Date modifiedOn; @OneToOne(mappedBy="reference") private ReferenceAdditionalDetails refAddDetails; . . . } 

Clase de niños:

 public class ReferenceAdditionalDetails implements Serializable{ private static final long serialVersionUID = 1L; @Id @OneToOne @JoinColumn(name="reference",referencedColumnName="id") private Reference reference; private String preferedSector1; private String preferedSector2; . . } 

En el caso anterior donde padre (Referencia) e hijo (ReferenceAdditionalDetails) tienen una relación OneToOne y cuando intenta crear la entidad Reference y luego su hijo (ReferenceAdditionalDetails), le dará la misma excepción. Para evitar la excepción, debe establecer null para la clase secundaria y luego crear la primaria. (Código de muestra)

 . . reference.setRefAddDetails(null); reference = referenceDao.create(reference); entityManager.flush(); . .