A simple Parent -> Child with @OneToMany children.
If have a detached object that has zero changes from the previously saved object and you call *session.merge()* a spurious update is generated if the Parent has an optimistic locking @Version field. However, no spurious update is generated if : * There is no @Version field * *session.saveOrUpdate()* is used instead of *session.merge()*
Here is the std-out to kind illustrate the issue. Note the *update* statement.
{code} ******** SAVE session.save() Hibernate: select child2x_.id, child2x_.name as name2_1_ from Child2 child2x_ where child2x_.id=? Hibernate: select child2x_.id, child2x_.name as name2_1_ from Child2 child2x_ where child2x_.id=? Hibernate: insert into ParentWithOptimisticLocking (name, VERSION, id) values (?, ?, ?) Hibernate: insert into Child2 (name, parent_id, child_index, id) values (?, ?, ?, ?) Hibernate: insert into Child2 (name, parent_id, child_index, id) values (?, ?, ?, ?) ================================================= Parent table after save ================================================= ID NAME VERSION 2b9ec59dabec4d6bad35bab64b9229ce barry 0 ================================================= ******** SAVE OR UPDATE THAT DOESN'T UPDATE Hibernate: select parentwith_.id, parentwith_.name as name2_2_, parentwith_.VERSION as VERSION3_2_ from ParentWithOptimisticLocking parentwith_ where parentwith_.id=? Hibernate: select child2x_.id, child2x_.name as name2_1_ from Child2 child2x_ where child2x_.id=? Hibernate: select child2x_.id, child2x_.name as name2_1_ from Child2 child2x_ where child2x_.id=? ******** GET BY ID Hibernate: select parentwith0_.id as id1_2_0_, parentwith0_.name as name2_2_0_, parentwith0_.VERSION as VERSION3_2_0_, children1_.parent_id as parent_i3_1_1_, children1_.id as id1_1_1_, children1_.child_index as child_in4_1_, children1_.id as id1_1_2_, children1_.name as name2_1_2_ from ParentWithOptimisticLocking parentwith0_ left outer join Child2 children1_ on parentwith0_.id=children1_.parent_id where parentwith0_.id=? ******** MERGE THAT SHOULDN'T UPDATE Hibernate: select parentwith0_.id as id1_2_1_, parentwith0_.name as name2_2_1_, parentwith0_.VERSION as VERSION3_2_1_, children1_.parent_id as parent_i3_1_3_, children1_.id as id1_1_3_, children1_.child_index as child_in4_3_, children1_.id as id1_1_0_, children1_.name as name2_1_0_ from ParentWithOptimisticLocking parentwith0_ left outer join Child2 children1_ on parentwith0_.id=children1_.parent_id where parentwith0_.id=? Hibernate: update ParentWithOptimisticLocking set name=?, VERSION=? where id=? and VERSION=? ================================================= Parent table. The version appears to have updated ================================================= ID NAME VERSION 2b9ec59dabec4d6bad35bab64b9229ce barry 1 ================================================= {code}
Here is Test case [^hibernate-merge-always-updates.zip] |
|