use of org.hibernate.test.jpa.Item in project hibernate-orm by hibernate.
the class JPALockTest method testLockModeTypeWrite.
/**
* Test the equivalent of EJB3 LockModeType.WRITE
* <p/>
* From the spec:
* <p/>
* If transaction T1 calls lock(entity, LockModeType.WRITE) on a versioned object, the entity
* manager must avoid the phenomena P1 and P2 (as with LockModeType.READ) and must also force
* an update (increment) to the entity's version column. A forced version update may be performed immediately,
* or may be deferred until a flush or commit. If an entity is removed beforeQuery a deferred version
* update was to have been applied, the forced version update is omitted, since the underlying database
* row no longer exists.
* <p/>
* The persistence implementation is not required to support calling lock(entity, LockMode-Type.WRITE)
* on a non-versioned object. When it cannot support a such lock call, it must throw the
* PersistenceException. When supported, whether for versioned or non-versioned objects, LockMode-Type.WRITE
* must always prevent the phenomena P1 and P2. For non-versioned objects, whether or
* not LockModeType.WRITE has any additional behaviour is vendor-specific. Applications that call
* lock(entity, LockModeType.WRITE) on non-versioned objects will not be portable.
* <p/>
* Due to the requirement that LockModeType.WRITE needs to force a version increment,
* a new Hibernate LockMode was added to support this behavior: {@link org.hibernate.LockMode#FORCE}.
*/
@Test
public void testLockModeTypeWrite() {
if (!readCommittedIsolationMaintained("ejb3 lock tests")) {
return;
}
final String initialName = "lock test";
// set up some test data
Session s1 = sessionFactory().openSession();
Transaction t1 = s1.beginTransaction();
Item item = new Item();
item.setName(initialName);
s1.save(item);
MyEntity myEntity = new MyEntity();
myEntity.setName("Test");
s1.save(myEntity);
t1.commit();
s1.close();
Long itemId = item.getId();
long initialVersion = item.getVersion();
s1 = sessionFactory().openSession();
t1 = s1.beginTransaction();
item = (Item) s1.get(Item.class, itemId);
s1.lock(item, LockMode.FORCE);
assertEquals("no forced version increment", initialVersion + 1, item.getVersion());
myEntity = (MyEntity) s1.get(MyEntity.class, myEntity.getId());
s1.lock(myEntity, LockMode.FORCE);
assertTrue("LockMode.FORCE on a un-versioned entity should degrade nicely to UPGRADE", true);
s1.lock(item, LockMode.FORCE);
assertEquals("subsequent LockMode.FORCE did not no-op", initialVersion + 1, item.getVersion());
Session s2 = sessionFactory().openSession();
Transaction t2 = s2.beginTransaction();
Item item2 = (Item) s2.get(Item.class, itemId);
assertEquals("isolation not maintained", initialName, item2.getName());
item.setName("updated-1");
s1.flush();
// currently an unfortunate side effect...
assertEquals(initialVersion + 2, item.getVersion());
t1.commit();
s1.close();
item2.setName("updated");
try {
t2.commit();
fail("optimistic lock should have failed");
} catch (Throwable ignore) {
// expected behavior
t2.rollback();
} finally {
s2.close();
}
s1 = sessionFactory().openSession();
t1 = s1.beginTransaction();
s1.delete(item);
s1.delete(myEntity);
t1.commit();
s1.close();
}
use of org.hibernate.test.jpa.Item in project hibernate-orm by hibernate.
the class JPALockTest method testLockModeTypeRead.
/**
* Test the equivalent of EJB3 LockModeType.READ
* <p/>
* From the spec:
* <p/>
* If transaction T1 calls lock(entity, LockModeType.READ) on a versioned object, the entity
* manager must ensure that neither of the following phenomena can occur:<ul>
* <li>P1 (Dirty read): Transaction T1 modifies a row. Another transaction T2 then reads that row and
* obtains the modified value, beforeQuery T1 has committed or rolled back. Transaction T2 eventually
* commits successfully; it does not matter whether T1 commits or rolls back and whether it does
* so beforeQuery or afterQuery T2 commits.
* <li>P2 (Non-repeatable read): Transaction T1 reads a row. Another transaction T2 then modifies or
* deletes that row, beforeQuery T1 has committed. Both transactions eventually commit successfully.
* <p/>
* This will generally be achieved by the entity manager acquiring a lock on the underlying database row.
* Any such lock may be obtained immediately (so long as it is retained until commit completes), or the
* lock may be deferred until commit time (although even then it must be retained until the commit completes).
* Any implementation that supports repeatable reads in a way that prevents the above phenomena
* is permissible.
* <p/>
* The persistence implementation is not required to support calling lock(entity, LockMode-Type.READ)
* on a non-versioned object. When it cannot support such a lock call, it must throw the
* PersistenceException. When supported, whether for versioned or non-versioned objects, LockMode-Type.READ
* must always prevent the phenomena P1 and P2. Applications that call lock(entity, LockModeType.READ)
* on non-versioned objects will not be portable.
* <p/>
* EJB3 LockModeType.READ actually maps to the Hibernate LockMode.OPTIMISTIC
*/
@Test
public void testLockModeTypeRead() {
if (!readCommittedIsolationMaintained("ejb3 lock tests")) {
return;
}
final String initialName = "lock test";
// set up some test data
Session s1 = sessionFactory().openSession();
Transaction t1 = s1.beginTransaction();
Item item = new Item();
item.setName(initialName);
s1.save(item);
t1.commit();
s1.close();
Long itemId = item.getId();
// do the isolated update
s1 = sessionFactory().openSession();
t1 = s1.beginTransaction();
item = (Item) s1.get(Item.class, itemId);
s1.lock(item, LockMode.UPGRADE);
item.setName("updated");
s1.flush();
Session s2 = sessionFactory().openSession();
Transaction t2 = s2.beginTransaction();
Item item2 = (Item) s2.get(Item.class, itemId);
assertEquals("isolation not maintained", initialName, item2.getName());
t1.commit();
s1.close();
item2 = (Item) s2.get(Item.class, itemId);
assertEquals("repeatable read not maintained", initialName, item2.getName());
t2.commit();
s2.close();
s1 = sessionFactory().openSession();
t1 = s1.beginTransaction();
s1.delete(item);
t1.commit();
s1.close();
}
use of org.hibernate.test.jpa.Item in project hibernate-orm by hibernate.
the class RepeatableReadTest method testStaleNonVersionedInstanceFoundInQueryResult.
@Test
public void testStaleNonVersionedInstanceFoundInQueryResult() {
String check = "Lock Modes";
Session s1 = sessionFactory().openSession();
Transaction t1 = s1.beginTransaction();
Part part = new Part(new Item("EJB3 Specification"), check, "3.3.5.3", new BigDecimal(0.0));
s1.save(part);
t1.commit();
s1.close();
Long partId = part.getId();
// Now, open a new Session and re-load the part...
s1 = sessionFactory().openSession();
t1 = s1.beginTransaction();
part = (Part) s1.get(Part.class, partId);
// now that the item is associated with the persistence-context of that session,
// open a new session and modify it "behind the back" of the first session
Session s2 = sessionFactory().openSession();
Transaction t2 = s2.beginTransaction();
Part part2 = (Part) s2.get(Part.class, partId);
part2.setName("Lock Mode Types");
t2.commit();
s2.close();
// at this point, s1 now contains stale data, so try an hql query which
// returns said part and make sure we get the previously associated state
// (i.e., the old name)
part2 = (Part) s1.createQuery("select p from Part p").list().get(0);
assertTrue(part == part2);
assertEquals("encountered non-repeatable read", check, part2.getName());
t1.commit();
s1.close();
// clean up
s1 = sessionFactory().openSession();
t1 = s1.beginTransaction();
s1.delete(part2);
s1.delete(part2.getItem());
t1.commit();
s1.close();
}
use of org.hibernate.test.jpa.Item in project hibernate-orm by hibernate.
the class RemovedEntityTest method testRemoveThenSave.
@Test
public void testRemoveThenSave() {
Session s = openSession();
s.beginTransaction();
Item item = new Item();
item.setName("dummy");
s.persist(item);
s.getTransaction().commit();
s.close();
Long id = item.getId();
s = openSession();
s.beginTransaction();
item = (Item) s.get(Item.class, id);
String sessionAsString = s.toString();
s.delete(item);
Item item2 = (Item) s.get(Item.class, id);
assertNull("expecting removed entity to be returned as null from get()", item2);
s.persist(item);
assertEquals("expecting session to be as it was beforeQuery", sessionAsString, s.toString());
item.setName("Rescued");
item = (Item) s.get(Item.class, id);
assertNotNull("expecting rescued entity to be returned from get()", item);
s.getTransaction().commit();
s.close();
s = openSession();
s.beginTransaction();
item = (Item) s.get(Item.class, id);
s.getTransaction().commit();
s.close();
assertNotNull("expecting removed entity to be returned as null from get()", item);
assertEquals("Rescued", item.getName());
// clean up
s = openSession();
s.beginTransaction();
s.delete(item);
s.getTransaction().commit();
s.close();
}
use of org.hibernate.test.jpa.Item in project hibernate-orm by hibernate.
the class RemovedEntityTest method testRemoveThenSaveWithCascades.
@Test
public void testRemoveThenSaveWithCascades() {
Session s = openSession();
s.beginTransaction();
Item item = new Item();
item.setName("dummy");
Part part = new Part(item, "child", "1234", BigDecimal.ONE);
// persist cascades to part
s.persist(item);
// delete cascades to part also
s.delete(item);
assertFalse("the item is contained in the session afterQuery deletion", s.contains(item));
assertFalse("the part is contained in the session afterQuery deletion", s.contains(part));
// now try to persist again as a "unschedule removal" operation
s.persist(item);
assertTrue("the item is contained in the session afterQuery deletion", s.contains(item));
assertTrue("the part is contained in the session afterQuery deletion", s.contains(part));
s.getTransaction().commit();
s.close();
// clean up
s = openSession();
s.beginTransaction();
s.delete(item);
s.getTransaction().commit();
s.close();
}
Aggregations