I have a parent class with the following field with cascading option:
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); }
}
In my application I want to add a child and then call JPA merge on the parent class, automatically persisting my new child. This all works, however, the origional child reference I inserted into my parent object has changed, meaning I cannot retrieve the ID of my persisted child. Is there any way I can tell hibernate to re-use my old child reference instead of making a new one? during the merge
Just get the merged instance of your parent:
parent = entityManager.merge(parent);
Update:
What you want is not possible. Either manually merge()
the child, and then add it to the parent, or get the new child instance from the parent collection and use it instead.
For many actions, Hibernate generates an event that can be listened for and some support code for listening.
If you're using Spring in conjunction with Hibernate, for instance, you can register a class org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener as a listener for hibernate's merge event (from I think spring-orm.jar) by putting the following in your hibernate.cfg.xml (or whatever file is referenced in your spring setup for hibernate config):
<event type="merge">
<listener class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/>
</event>
or by adding an map in your sessionFactory bean:
<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>
If you do either of these, this listener should set the id in the original object. If you're not using Spring, there's likely a way to get a listener connected that's similar to one of these.
I haven't tested the child behavior you're looking for, but I'm pretty sure that a merge on the parent will trigger a merge on the child so that the listener will be called for both.
The setup for JPA might be different, but I suspect it's possible, and hope this gives clues.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With