Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

214
Vistas
Cómo hacer una copia de la colección de hibernación con cascade="all,delete-orphan"

Estoy tratando de hacer una copia de una entidad de hibernación A como esta:

 A a = (A) session.get(A.class, id); session.evict(a); a.setId(null); session.save(a);

Sin embargo, esto no funciona y obtengo la siguiente experiencia:

 org.hibernate.HibernateException: Don't change the reference to a collection with cascade="all-delete-orphan": com.test.AB

Es seguro asumir que este error ocurre porque tengo una colección de entidades B definidas en la entidad A:

 <list name="B" table="B" lazy="false" cascade="all,delete-orphan"> <key column="A_ID" not-null="true"/> <index column="X"/> <one-to-many class="com.test.B"/> </list>

¿Cómo es posible hacer una copia de la entidad A, incluida su colección de entidades B sin que Hibernate esté descontento con eso?

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Si desea copiar una entidad existente, modificarla y guardarla como una nueva entidad, debe realizar una copia profunda de ese objeto. Puede hacer una copia profunda de un objeto serializando y luego deserializando ese objeto.

 public Object deepCopy(Object input) { Object output = null; try { // Writes the object ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); objectOutputStream.writeObject(input); // Reads the object ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); output = objectInputStream.readObject(); } catch (Exception e) { e.printStackTrace(); } return output; }
over 4 years ago · Santiago Trujillo Denunciar

0

Tuve el mismo problema anteriormente en mi proyecto.

Para mí funciona, establecer la ID de las entradas de la lista en nulo.

 // make copy a of aOriginal by using serialisation clone a.setId(null); for (B b : a.getBs()) { b.setId(null); } session.save(a);

Para el clon en sí, utilicé el clon de Apache SerializationUtils .

La razón es que hibernate intenta "reutilizar" las entradas de la lista ya persistentes para la entidad "copiada". Pero estas entradas de lista ya persistentes están vinculadas a una entidad original. Entonces intenta "cambiar" la lista en sí misma en la entidad, porque la entidad cambió. Pero no puede cambiar la lista si está anotada con "eliminar huérfanos" (solo puede modificar las entradas de la lista, pero no la lista en sí). Así que se lanza la excepción.

Si configuro los ID de entrada de lista en nulo, también se insertarán newley. Y la jerarquía de objetos (en lugar de solo la entidad principal) se duplica. Entonces la excepción ya no se lanza.

over 4 years ago · Santiago Trujillo Denunciar

0

No hay una forma automática de copiar objetos como ese. En general, el objeto copiado podría estar asociado con otros objetos que están más asociados con otros objetos, etc., por lo que podría terminar copiando una gran parte de la base de datos. Cualquier herramienta que utilice para copiar debe saber en qué parte del gráfico de objetos debe dejar de copiar, qué no copiar (en términos de entidades de Hibernate, son ids, columnas de versión y similares), etc.

Sin embargo, puede utilizar marcos como Dozer para evitar la mayor parte del código repetitivo que necesitaría escribir manualmente.

Con respecto al problema de la reasignación de la colección, no puede tener la misma colección de instancias B asignadas a dos A diferentes, ya que lógicamente sería una asociación many-to-many . También es algo de lo que debería encargarse manualmente, ya que es específico para el caso de uso de su negocio.

Además, asegúrese de no reutilizar los mismos proxies de colección de una instancia de entidad en otras, ya que Hibernate los vincula a sus padres originales internamente; siempre cree una nueva colección en nuevas instancias (que pueden o no contener los mismos elementos).

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda