Missing flush before lock() when LockModeType is AUTO
-----------------------------------------------------
Key: EJB-328
URL:
http://opensource.atlassian.com/projects/hibernate/browse/EJB-328
Project: Hibernate Entity Manager
Issue Type: Bug
Components: EntityManager
Affects Versions: 3.3.1.GA
Environment: core: 3.2.5.ga
entitymanager: 3.3.1.ga
annotations: 3.3.0.ga
Reporter: Per Olesen
Priority: Minor
When I try to WRITE lock() a newly persisted entity using entityManager.lock, I get a
StaleObjectStateException, telling me that some other transaction updated or deleted the
row. I am doing this in the same transaction (persist and lock).
By digging into the code, I see that the exception is thrown inside the
SelectLockingStrategy.lock method, around these lines:
ResultSet rs = st.executeQuery();
try {
if ( !rs.next() ) {
if ( factory.getStatistics().isStatisticsEnabled() ) {
factory.getStatisticsImplementor()
.optimisticFailure( lockable.getEntityName() );
}
throw new StaleObjectStateException( lockable.getEntityName(), id );
}
}
The query executed here is the one which performs the select on id with FOR UPDATE. This
select finds nothing, hence the exception.
Setting show_sql = true shows me, that no insert is performed. Debugging the flush mode
tells me, that it is set to AUTO.
Shouldn't AUTO flush mode have the side effect, that a flush is performed before a
query?
Performing an explicit flush, before the lock, makes everything green :-), so this is my
current work-around.
Here is the exception (sanitized for company info):
org.springframework.orm.jpa.JpaOptimisticLockingFailureException: nested exception is
javax.persistence.OptimisticLockException
Caused by: javax.persistence.OptimisticLockException
at
org.hibernate.ejb.AbstractEntityManagerImpl.wrapStaleStateException(AbstractEntityManagerImpl.java:643)
at
org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:600)
at org.hibernate.ejb.AbstractEntityManagerImpl.lock(AbstractEntityManagerImpl.java:379)
...
Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted by another
transaction (or unsaved-value mapping was incorrect): [com.foo.bar#32]
at org.hibernate.dialect.lock.SelectLockingStrategy.lock(SelectLockingStrategy.java:78)
at
org.hibernate.persister.entity.AbstractEntityPersister.lock(AbstractEntityPersister.java:1334)
at
org.hibernate.event.def.AbstractLockUpgradeEventListener.upgradeLock(AbstractLockUpgradeEventListener.java:88)
at
org.hibernate.event.def.DefaultLockEventListener.onLock(DefaultLockEventListener.java:64)
at org.hibernate.impl.SessionImpl.fireLock(SessionImpl.java:584)
at org.hibernate.impl.SessionImpl.lock(SessionImpl.java:576)
at org.hibernate.ejb.AbstractEntityManagerImpl.lock(AbstractEntityManagerImpl.java:376)
...
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira