views:

179

answers:

2

Consider two entities Parent and Child.

  • Child is part of Parent's transient collection
  • Child has a ManyToOne mapping to parent with FetchType.LAZY

Both are displayed on the same form to a user. When user saves the data we first update Parent instance and then Child collection (both using merge).

Now comes the tricky part. When user modifies only Child property on the form then hibernate dirty checking does not update Parent instance and thus does not increase optimistic locking version number for that entity.

I would like to see situation where only Parent is versioned and every time I call merge for Parent then version is always updated even if actual update is not executed in db.

+1  A: 

I think I figured it out. After merge is called an attached instance reference is returned. When I obtain an explicit lock for that using entityManager.lock(updated, LockModeType.WRITE); then version number is increased even if Parent instance was not updated in db.

In addition I am comparing detached instance version with persisted instance version. If they don't match then Parent was updated in db and also version number has changed. This keeps version numbers consistent. Otherwise entityManager.lock would increase version number even if merge operation changed it.

Still looking for solution how to make hibernate increase version when entity is not dirty during merge.

Priit
+1 for locking solution
oedo
A: 

i don't think you can force hibernate to increase a version number for a non-changed object, because it will just not do any db UPDATE query if nothing has changed (for obvious reasons).

you could do a nasty hack like adding a new field to the object and incrementing that manually, but personally that seems to be a waste of time and resources. i'd go with your explicit locking solution since that seems to give you what you want, without unnecessary hackery.

oedo