2010-02-01 11 views
7

tengo una clase padre con el siguiente campo con cascada opción:Hibernate (APP) en cascada - recuperar Identificación del niño

public class Parent { 
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL) 
    @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN) 
    private final Set<Child> children = new HashSet<Child>(); 
    public addChild(Child child) { children.add(child); } 
} 

En mi solicitud Quiero añadir un niño y luego llamar a la APP se funden en la matriz clase, persistiendo automáticamente a mi nuevo hijo. Todo esto funciona, sin embargo, la referencia de niño original que inserté en mi objeto principal ha cambiado, lo que significa que no puedo recuperar la identificación de mi hijo persistente. ¿Hay alguna manera de decirle a hibernate que vuelva a utilizar mi referencia de hijo mayor en lugar de crear una nueva? durante la fusión

Respuesta

1

acaba de obtener la instancia resultante de la fusión de sus padres:

parent = entityManager.merge(parent); 

Actualización:

Lo que queremos no es posible. O manualmente merge() el hijo, y luego agréguelo al padre, u obtenga la nueva instancia hija de la colección primaria y úsela en su lugar.

+0

Lo sé, pero solo obtengo la instancia combinada de mi padre. Quiero que la instancia fusionada de mi hijo recupere su ID. Por supuesto que puedo recuperar el último elemento del conjunto de mis hijos, pero eso es increíblemente desagradable. – Jeroen

+0

debería tenerlos también, como parte del nuevo padre. – Bozho

+0

Deseo hacer lo siguiente: Child child = new Child(); parent.addChild (child); service.saveParent (principal); // hacer cosas con la referencia secundaria persistente p. Ej. child.getId(); – Jeroen

1

Para muchas acciones, Hibernate genera un evento que se puede escuchar y un código de soporte para escuchar.

Si está utilizando Spring junto con Hibernate, por ejemplo, puede registrar una clase org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener como escucha para el evento de fusión de hibernate (de Creo que spring-orm.jar) poniendo lo siguiente en su hibernate.cfg.xml (o cualquier archivo se hace referencia en la configuración de la primavera de configuración de hibernación):

<event type="merge"> 
     <listener class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/> 
    </event> 

o añadiendo un mapa en su frijol sessionFactory:

<bean id="sessionFactory" 
      class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" 
      p:dataSource-ref="dataSource"> 
    <property name="configLocation" value="WEB-INF/classes/hibernate.cfg.xml"/> 
    <property name="eventListeners"> 
      <map> 
        <entry key="merge"> 
          <bean class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/> 
        </entry> 
      </map> 
    </property> 

Si hace cualquiera de estos, este oyente debe establecer la identificación en el objeto original. Si no está utilizando Spring, es probable que haya una forma de conectar un oyente que sea similar a uno de estos.

No he probado el comportamiento secundario que está buscando, pero estoy bastante seguro de que una combinación en el padre desencadenará una fusión en el niño para que se llame al oyente por ambos.

La configuración de JPA puede ser diferente, pero sospecho que es posible, y espero que esto dé pistas.

+0

Pude agregar el oyente a mi persistence.xml Sin embargo, ahora recibo una OptimisticLockException al guardar un objeto con elementos en cascada – Jeroen

+0

OptimisticLockException se lanzó porque he declarado un atributo @Version en cada uno de mis modelos de dominio. Finalmente resolví este problema extendiendo IdTransferringMergeEventListener y copiando el valor de mi versión del resultado en el original. Muchas gracias por apuntarme en la dirección correcta! – Jeroen

+0

Me alegro de que haya ayudado, y espero que no cause problemas en otros lugares. No he usado esto en un contexto JPA, y no lo hago saber el impacto completo –

Cuestiones relacionadas