| A typical use case is passing version from hidden field of UI form to detect version conflict, but EntityEntry always use the version loaded from database, change managed entity version doesn't make sense.
@Test(expected = OptimisticLockException.class)
public void testManagedEntity() throws Exception {
Session s = openSession();
Transaction tx = s.beginTransaction();
Company company = new Company();
assertEquals(-1, company.getVersion());
company.setName("a");
s.save(company);
tx.commit();
tx = s.beginTransaction();
assertEquals(0, company.getVersion());
company.setName("b");
s.update(company);
tx.commit();
tx = s.beginTransaction();
assertEquals(1, company.getVersion());
company.setName("c");
company.setVersion(company.getVersion() - 1); s.update(company);
tx.commit();
tx = s.beginTransaction();
assertEquals(2, company.getVersion());
s.close();
}
this test case will fail.
@Test(expected = OptimisticLockException.class)
public void testDetachedEntity() throws Exception {
Session s = openSession();
Transaction tx = s.beginTransaction();
Company company = new Company();
assertEquals(-1, company.getVersion());
company.setName("a");
s.save(company);
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
assertEquals(0, company.getVersion());
company.setName("b");
s.update(company);
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
assertEquals(1, company.getVersion());
company.setName("c");
company.setVersion(company.getVersion() - 1); s.update(company);
tx.commit();
assertEquals(2, company.getVersion());
s.close();
}
this test case will pass. My solution is add setVersion() method for EntityEntry, and call it before flush
entry.setVersion(Versioning.getVersion(values, persister));
|