1 Reply Latest reply: Sep 28, 2011 3:47 PM by bora bora RSS

EntityManager lifecycle

bora bora Newbie

Hi all,


This may be a question better asked at the Hibernate forums but it is also closely related (at least I would think so) with the lifecycle of the entityManager in a Seam Asynchronous Event context. So here it goes...


I have a database table that is updated in a highly concurrent manner.
Further, the updates are done via different asynchronous event handlers.


I have put a version property in the entity class to get optimistic lock exceptions in order not to have any lost updates.
But instead of retrying the update operation after getting an optimistic lock, I am trying to avoid those exceptions completely by properly synchronizing the Java code that updates the table.


So for example a single thread calls below method to update an entity instance:


public void updateMethod(Long id) {
    synchronized(GLOBAL_LOCK) {
        EntityManager entityManager = (EntityManager) Component.getInstance("entityManager");
        SomeEntity entity = entityManager.find(SomeEntity.class, id);
        entityManager.refresh(entity);
        entityManager.lock(entity, LockModeType.WRITE);
        // do some stuff to modify the entity
        entityManager.flush();
    }
}



Here even though I am synchronizing the method on a global level (lock is a singleton per JVM), I get javax.persistence.OptimisticLockException.
- javax.persistence.OptimisticLockException: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)


I am simply wondering how this can happen even though the EntityManager objects and the underlying transactions are different in different threads. I checked this by debugging and verified it: they are different in different asynchronous events. Since the transactions and entityManager's are different instances and the code is mutually exclusive, I shouldn't be hitting any OptimisticLockException's right? Any ideas why this is happening?


I will now test with entityManager.close() added after the flush() but not sure if it will help.


As far as I know, entityManager's are scoped to Conversation's. But here they are created in an Async Event context. What would be the lifecycle of the entityManager in this context? I couldn't find any information about it in the manual.


Any feedback is appreciated.


Seam version: 2.1.2


Regards,
Bora.