Why does a hibernate session ignore changes to an @Version column?
Consider the situation where I load an object from DB and then update elements of it with the intention of persisting those changes--all within a single Hibernate session. If I change the "name" field of my bean and then merge, the change will commit to the DB. However, if I change the version column (annotated @Version) and then merge, the change gets ignored and doesn't throw the StaleObjectException as it should.
This is particularly a problem for me when using spring's OpenEntityManagerInViewFilter when the same Hibernate session is used to pull the data (using Spring's prepare interceptor) from the DB and then update it within the same http request (same hibernate session).
In junit, this test will fail w/ OptimisticLockException (the behavior I would expect)--here the merge uses a different EntityManager:
Code:
@Test
public void testSupplierCompanyBean() throws Exception {
EntityManager em = emf.createEntityManager();
EntityManager em3 = emf.createEntityManager();
MyBean b = em.find(MyBean.class, 100);
b.setVersion(b.getVersion() - 1);
b=em3.merge(b);
}
whereas this one will pass ( no StaleObject or OptimisticLock exceptions thrown) and instead of a version that is decremented (current -1), the resulting DB would have an incremented version.
Code:
@Test
public void testSameEntityManagerMerge() throws Exception {
EntityManager em = emf.createEntityManager();
MyBean b = em.find(MyBean.class, 100);
b.setVersion(b.getVersion() - 1);
b=em.merge(b);
}
In the second case the object is still attached to em, however I don't see why hibernate doesn't notice that the version has changed and throw the StaleObjectException.