[hibernate-issues] [Hibernate-JIRA] Created: (HHH-5514) Add ability to lock / reattach an entity with a dirty collection

Steve McIntyre (JIRA) noreply at atlassian.com
Mon Aug 30 23:15:18 EDT 2010


Add ability to lock / reattach an entity with a dirty collection
----------------------------------------------------------------

                 Key: HHH-5514
                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-5514
             Project: Hibernate Core
          Issue Type: New Feature
          Components: core
         Environment: 3.3.2.GA, Oracle 10g
            Reporter: Steve McIntyre


We are using Hibernate 3.3.2.GA, with optimistic locking via @Version and the session per request pattern (and thus detached entity object graphs).

We have a very complex object graph consisting of carts, orders, line items, sub line items, payments, delivery, sub line item deliveries, etc. In most situations, our cart executes against a single order. However, there are cases where multiple orders can be involved. Our orders can be fairly large in terms of the number of line items, sub items, etc. As a result, as users navigate the application we only load the orders they request.

The issue gets more complex if two orders (e.g. order #1 and #2) are involved in multiple carts. Why? Some entities in the object graph (e.g. carts, payments, deliveries, etc) can span orders and transactions. Consider a multiple-step/session cart where we load order #1, associate it with a new cart and detach the object graph. The user subsequently requests elements from order #2 be loaded into the new cart. So, we load order #2, associate it with the same/new cart and detach the object graph.

Now, if in a previous cart/transaction, orders #1 and #2 shared a (eg) delivery, when we load #2 and its associated delivery, in order to avoid two instances of this same delivery in our detached object graph, we need to re-attach the previously loaded delivery to the new session, prior to loading order #2.

Since we are not ready to persist changes to the database yet, and because this delivery may be dirty, we choose to use Hibernate's "lock" API (as opposed to refresh, load, merge, update, etc) to re-attach the delivery in our graph to the current session. 

All this works great except that if our delivery entity has a pesisted collection that has been modified, a "reassociated object has dirty collection" Hibernate exception is thrown.

We could work around this situation by adding a new collection to our delivery entity that maintained changes to the pesisted collection, then just prior to calling "merge" we could move the changes to the persistence collection. However, as I mentioned we have a complex object graph... that involves 10 entities with a total of 23 persisted collections we'd have to manage this way for this one aspect of our system.

As an experiment, I commented out one line in the org.hibernate.event.def.OnLockVisitor class, processCollection method (below) to no longer throw the exception.

{noformat} 
if ( persistentCollection.isDirty() ) {
  // Don't throw exception hack
  // throw new HibernateException( "reassociated object has dirty collection" );
}
reattachCollection( persistentCollection, type );
{noformat} 

and returned early from org.hibernate.event.def.DefaultLockEventListener class, onLock method (below)
{noformat} 
if ( !ForeignKeys.isNotTransient( event.getEntityName(), entity, Boolean.FALSE, source ) ) {
  return; // Return early hack
  // throw new TransientObjectException(
  // "cannot lock an unsaved transient instance: " +
  // persister.getEntityName()
  // );
}
{noformat} 


With these two changes, I was able to lock / re-attach all the necessary entities in our detached object graph, and subsequently was able to merge the entire graph successfully.

My questions to the Hibernate team are:

1) Is there already existing functionality that could achieve the same results (e.g. re-attach detached entities that contain dirty persistence collections to a new session )?

2) Would they consider adding another org.hibernate.LockMode type (e.g. DIRTY) that would support the behavior I've described above? If so on this latter option, I would be happy to work on the code fix to support the DIRTY or maybe DIRTY_COLLECTION lock mode.


-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the hibernate-issues mailing list