Cómo solucionar el error "el objeto de Hibernate hace referencia a una instancia transitoria no guardada: guarde la instancia transitoria antes de vaciarla"
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 el mapeo de su 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 padre.
Creo que esto podría ser solo una respuesta repetida, pero solo para aclarar, obtuve esto en un @OneToOne
mapeo y en un archivo @OneToMany
. En ambos casos, fue el hecho de que el Child
objeto que estaba agregando Parent
aún no se había guardado en la base de datos. Entonces, cuando agregué el Child
y Parent
luego guardé el Parent
, Hibernate arrojaría el "object references an unsaved transient instance - save the transient instance before flushing"
mensaje al guardar el Padre.
Agregando la cascade = CascadeType.ALL
referencia Parent's
al Child
problema resuelto en ambos casos. Esto salvó el Child
y el Parent
.
Perdón por las respuestas repetidas, solo quería aclarar más a la gente.
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "performancelog_id")
public PerformanceLog getPerformanceLog() {
return performanceLog;
}
Introducción
Cuando se utiliza JPA e Hibernate, una entidad puede estar en uno de los siguientes 4 estados:
- Nuevo : un objeto recién creado que nunca se ha asociado con una sesión de hibernación (también conocido como contexto de persistencia) y no está asignado a ninguna fila de la tabla de la base de datos se considera en estado nuevo o transitorio.
Para persistir necesitamos llamar explícitamente al persist
método o hacer uso del mecanismo de persistencia transitiva.
- Persistente : una entidad persistente se ha asociado con una fila de la tabla de la base de datos y está siendo administrada por el contexto de persistencia actualmente en ejecución.
Cualquier cambio realizado en dicha entidad será detectado y propagado a la base de datos (durante el tiempo de vaciado de la sesión).
Separado : una vez que se cierra el contexto de persistencia que se está ejecutando actualmente, todas las entidades administradas anteriormente se desconectan. Ya no se realizará un seguimiento de los cambios sucesivos y no se realizará ninguna sincronización automática de la base de datos.
Eliminado : aunque JPA exige que solo se permita eliminar entidades administradas, Hibernate también puede eliminar entidades separadas (pero solo mediante una
remove
llamada a un método).
Transiciones de estado de entidad
Para mover una entidad de un estado a otro, puede utilizar los métodos persist
o .remove
merge
Solucionando el problema
El problema que estás describiendo en tu pregunta:
object references an unsaved transient instance - save the transient instance before flushing
se produce al asociar una entidad en el estado New a una entidad que está en el estado Managed .
Esto puede suceder cuando asocia una entidad secundaria a una colección de uno a muchos en la entidad principal y la colección no realiza cascade
las transiciones de estado de la entidad.
Por lo tanto, puede solucionar este problema agregando cascada a la asociación de entidad que desencadenó este error, de la siguiente manera:
La @OneToOne
Asociación
@OneToOne(
mappedBy = "post",
orphanRemoval = true,
cascade = CascadeType.ALL)
private PostDetails details;
Observe el
CascadeType.ALL
valor que agregamos para elcascade
atributo.
La @OneToMany
Asociación
@OneToMany(
mappedBy = "post",
orphanRemoval = true,
cascade = CascadeType.ALL)
private List<Comment> comments = new ArrayList<>();
Nuevamente, CascadeType.ALL
es adecuado para las @OneToMany
asociaciones bidireccionales.
Ahora, para que la cascada funcione correctamente de forma bidireccional, también debe asegurarse de que las asociaciones principal e secundaria estén sincronizadas.
La @ManyToMany
Asociación
@ManyToMany(
mappedBy = "authors",
cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
}
)
private List<Book> books = new ArrayList<>();
En una @ManyToMany
asociación, no puede usar CascadeType.ALL
o, orphanRemoval
ya que esto propagará la transición del estado de eliminación de la entidad de una entidad principal a otra entidad principal.
Por lo tanto, para @ManyToMany
las asociaciones, normalmente las operaciones CascadeType.PERSIST
u se ponen en cascada CascadeType.MERGE
. Alternativamente, puede expandirlo a DETACH
o REFRESH
.