Odi's astoundingly incomplete notes

New entries | Code

Updates done right in EJB3

The EJB3 specs are very well designed. The decision to use it finally paid off!

I was facing the following problem: A structure of objects that is already present in the database needs to be updated with new data from memory. The structure is complex (a more complex graph than a tree) and has lots of relationships back and forth in the object model. The problem can not be solved by first deleting the existing data and then inserting the new data because the existing data is referenced to from other objects. (Some delete operations would lead to foreign key constraint violations.)

So it is necessary to use the EntityManager.merge operation. We have not defined any persistence cascading, so objects need to be merged one by one. For this to succeed it must be done like so in exactly this order:
  1. Find existing persistent objects that corresonds to the new objects.
  2. Copy the primary key (ID fields) and version numbers of all persistent objects to the new objects. This effectively makes them detached entities.
  3. Merge all objects. The order is unimportant.
The EJB3 specs support this by two requirements:
  1. Guaranteed object identity: Managed objects with the same primary key are identical instances.
  2. EntityManager.merge produces referenced entities that are managed: As outlined in section of the persistence specs.
This means that after merging you have a consistent persistent object structure. There is no need to take special care of all the relationships.

Let me illustrate this by the following diagram:

We start with X and Y which are two new, transient objects. X holds a reference to Y. After setting the ID and version of X and Y, merge is called on X. This creates a managed object X' which references a managed object Y'. Y' is automatically fetched from the database using the ID of Y. Now calling merge on Y will copy the data to the instance Y'. There is no need to manually relate X' and Y' again!

posted on 2006-03-08 15:22 UTC in Code | 0 comments | permalink