Code [0] fails with [1]. I am just trying to pesimistically lock an entity in the same transaction where I created it.
Cause is that 1) Entity has SEQUENCE id generator, Hibernate doesn't flush before the find() nor before the lock(). 2) With PESSIMISTIC_WRITE Hibernate has to issue SELECT FOR UPDATE.
Because entity is not inserted at the time of the SELECT FOR UPDATE, the find/lock fails....
Currently I workaround this by flushing before acquiring the pessimistic lock.
[0] { noformat code:java } package cz.nguyen;
import java.sql.SQLException;
import javax.persistence.*; public class Main { private static EntityManagerFactory emf;
@Entity public static class Employee {
@Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private Long id;
}
public static void main(String[] args) throws SQLException { emf = Persistence.createEntityManagerFactory("default"); EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); Employee e = new Employee(); em.persist(e);
em.find(Employee.class, 1l, LockModeType.PESSIMISTIC_WRITE); // Same behavior with: // em.lock(e, LockModeType.PESSIMISTIC_WRITE); em.close(); emf.close(); }
}
{ noformat code } [1] {noformat} Exception in thread "main" javax.persistence.OptimisticLockException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [cz.nguyen.entity.Employee#1] at org.hibernate.internal.ExceptionConverterImpl.wrapStaleStateException(ExceptionConverterImpl.java:202) at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:88) at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:176) at org.hibernate.internal.SessionImpl.find(SessionImpl.java:3431) at org.hibernate.internal.SessionImpl.find(SessionImpl.java:3381) at cz.nguyen.Main.main(Main.java:27) Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [cz.nguyen.entity.Employee#1] at org.hibernate.dialect.lock.PessimisticWriteSelectLockingStrategy.lock(PessimisticWriteSelectLockingStrategy.java:76) at org.hibernate.persister.entity.AbstractEntityPersister.lock(AbstractEntityPersister.java:1802) at org.hibernate.event.internal.AbstractLockUpgradeEventListener.upgradeLock(AbstractLockUpgradeEventListener.java:82) at org.hibernate.event.internal.DefaultLoadEventListener.loadFromSessionCache(DefaultLoadEventListener.java:566) at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:441) at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:219) at org.hibernate.event.internal.DefaultLoadEventListener.lockAndLoad(DefaultLoadEventListener.java:403) at org.hibernate.event.internal.DefaultLoadEventListener.doOnLoad(DefaultLoadEventListener.java:124) at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:89) at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1239) at org.hibernate.internal.SessionImpl.access$1900(SessionImpl.java:203) at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.doLoad(SessionImpl.java:2797) at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.load(SessionImpl.java:2778) at org.hibernate.internal.SessionImpl.find(SessionImpl.java:3407) ... 2 more
{noformat}
|
|