Our group just started using Hibernate with AndroMDA and Spring. We have several parent to child one-to-many associations in our DB. Our application requires the use of DTOs or VOs. So we have a situation where we have VOs which mimic the associations of our Hibernate entities.
So we have a ParentVO containing a collection of ChildVOs. We then need to persist this to the DB, doing an update, adding and deleting children as necessary. I was flailing on this on for a while and came up with the following solution. I'm wondering if others have had to do this and if so, what solution they chose.
The code below just shows the part of the problem where we are updating the Parent with the ParentVO. This is all done inside of a session, so eventually will get updated when the session exits.
Code:
Parent parent = session.load(Parent.class, ParentVO.getId());
// ... some code to copy parentVO attributes onto parent.
Collection<Child> children = parent.getChildren();
HashSet<Long> childIds = new HashSet<Long>();
HashSet<Children> childrenToRemove = new HashSet<Children>();
// get an id list of the desired child collection
for (ChildVO childVO : parentVO.getChildren())
childIds.add(childVO.getId());
// find out which persisted children no longer belong
for (Child child : children) {
if (!childIds.contains(child.getId()))
childrenToRemove.add(child);
}
// remove the persisted children that don't belong from the persisted collection
for (Child child : childrenToRemove)
children.remove(child);
// add or update the children that are in the parentVO.
//
for (ChildVO childVO : parentVO.getChildren()) {
Child child = util.childVOtoChild(childVO);
child.setParent(parent);
children.add(child);
}
Seems a bit convoluted right? But this is the only way I could figure out how to get delete-orphan to work. We unfortunately do not have access to the detached Parent (and thus the original Child collection) to operate on at the web tier. So we have to create a ParentVO and associated ChildVOs that represent the update we want to occur. We then (as you see above) need to get a Persistent version of the parent and perform our changes on it.
I tried to call
Parent.getChildren().clear() and then add all the children, but this does not work because some of the children represent updates (the
util.childVOtoChild() method will return a Persistent entity if it already existed), but this will generate an Exception because the Persistent object will have already been deleted in the session if clear was called.
Is there a better way?
Thanks,
Martin