Search code examples
javahibernatejpaconcurrencyejb

JPA 1.0 and Hibernate 3.4 generating FOR UPDATE NOWAIT when locking


I am currently working on a Java EJB project being deployed to Weblogic 10.3.3. We are using JPA 1.0 with Hibernate 3.4 as the implementor. We are also using the Oracle10g Dialect.

The issue we are running in to involves the generation of SQL by hibernate when attempting to lock a row for update.

We execute a query:

Query q = entityManager.createNamedQuery("findMyObject");    
MyHibernateObject myObject= (MyHibernateObject ) q.getSingleResult();

And then lock that object with:

entityManager.lock(myObject, LockModeType.WRITE);

This act of locking generates the query:

SELECT myObject FROM myTable FOR UPDATE NOWAIT

What I want it to generate is:

SELECT myObject FROM myTable FOR UPDATE

Enabling other threads to query for this object without throwing the exception: org.hibernate.exception.LockAcquisitionException and to just wait their turn or let the EJB transaction timeout.

So knowing all this, can I force Hibernate to generate the SQL without the NOWAIT keyword?

I know that using Hibernate 3.6 and JPA 2.0 will allow this using a pessimistic lock but due to Weblogic only supporting JPA 1.0 our hands are tied.

Ideally I want to avoid writing our own retry and/or timeout mechanism by handling the exception when all I need is to just augment the SQL that Hibernate is generating when the EntityManager creates the lock.


Solution

  • Ok, we are using a workaround until we update to Weblogic 10.3.4

    Here it is in case someone else stumbles upon this:

    SessionImpl session = (SessionImpl)entityManager.getDelegate();
    session.lock(myObject, LockMode.UPGRADE);
    

    This of course breaks from the JPA standard, in that we are exposing hibernates implementation and using the hibernate session.

    But it will generate a

    SELECT myObject FOR UPDATE
    

    instead of

    SELECT myObject FOR UPDATE NOWAIT
    

    Hope this helps someone.