We have run into the following issue with Hibernate.
I have a parent object with a collection of children in the hibernate session. I also have a detached parent object from a form submission that does not have the collection of childern. Now I do a merge so that I can save the updates to the parent object. If the cascade on the relationship is set to "all-delete-orphan", the children are deleted - as I expect. However, when the the cascade is set to "save-update,delete-orphan", the children are also deleted. I would expect that the children would not be deleted in this case since I am not cascading on merge.
To work around this issue, we have implemented a shallow merge as follows:
Code:
public static BaseDomain shallowMerge( BaseDomain sourceDomainObject, SessionImplementor session )
{
BaseDomain sessionObject = (BaseDomain)session.get( sourceDomainObject.getClass(),
sourceDomainObject.getId() );
EntityPersister persister = session.getEntityPersister( null, sessionObject );
Type[] types = persister.getPropertyTypes();
String[] propertyNames = persister.getPropertyNames();
for ( int i = 0; i < types.length; i++ )
{
Type type = types[i];
if ( ! ( type instanceof AssociationType ) )
{
String propertyName = propertyNames[i];
try
{
Object sourceObjectPropertyValue = PropertyUtils.getSimpleProperty( sourceDomainObject,
propertyName );
PropertyUtils.setSimpleProperty( sessionObject, propertyName, sourceObjectPropertyValue );
}
catch( Exception e )
{
//throw exception
}
}
}
Is there something that I am missing? Is this a good solution? Should Hibernate not exibit this behavior, or is this by design? I'm not sure if the delete-orphan is causing this, but we do want the delete-orphan cascade.
I also noticed in the replace method of the TypeFactory which is called on a merge has the following code
Code:
if ( original[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY
|| original[i] == BackrefPropertyAccessor.UNKNOWN ) {
copied[i] = target[i];
}
else {
copied[i] = types[i].replace( original[i], target[i], session, owner, copyCache );
}
If I could set the original property to UNFETCHED_PROPERTY or UNKNOWN then that would solve the problem too. Can I do that?