views:

611

answers:

2

When trying to setup a lock (pessimistic), with the following code:

em.lock(controlnumbers, LockModeType.WRITE);
em.refresh(controlnumbers);

I am getting the following exception:

[#|2009-09-10T15:42:48.324-0400|INFO|sun-appserver2.1|javax.enterprise.system.container.ejb|_ThreadID=31;_ThreadName=httpSSLWorkerThread-8080-19;|
javax.ejb.TransactionRolledbackLocalException: Exception thrown from bean; nested exception is: javax.persistence.PersistenceException: ejb30-wrong-lock_called_without_version_locking-index (There is no English translation for this message.)
javax.persistence.PersistenceException: ejb30-wrong-lock_called_without_version_locking-index (There is no English translation for this message.)
        at oracle.toplink.essentials.internal.ejb.cmp3.base.EntityManagerImpl.lock(EntityManagerImpl.java:619)
        at com.sun.enterprise.util.EntityManagerWrapper.lock(EntityManagerWrapper.java:582)
        at com.eximtechnologies.transactionserver.persistence.session.ControlNumbersFacade.lock(ControlNumbersFacade.java:43)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

How can I implement pessimistic locking with Glassfish 2.1?

A: 

Can you show the mapping for your class? It looks like you are missing a version property... Take a look at

http://en.wikibooks.org/wiki/Java%5FPersistence/Locking#Timestamp%5FLocking

Regards, Jan

Jan
That would work if I wanted optimistic locking. As the question states, I want pessimistic locking. :)
jsight
According to EJB3-specifiation, lock() is only supported for entities with a @version attribute.
Jan
@Jan - That's nice, but doesn't answer the question. :) Most containers have the ability to support pessimistic locking (in some container specific way). Glassfish does as well, via query hints... :)
jsight
+2  A: 

There is a Toplink Essentials (GF 2.1 default) specific way to do this:

public MyObject lock (MyObject controlnumbers) {
    String qStr = "select object(o) from MyObject as o where o.pk = :pk";
    Query q = em.createQuery(qStr);
    q.setParameter("pk", "a");
    q.setHint("toplink.pessimistic-lock", "Lock");
    controlnumbers = (MyObject)q.getSingleResult();
    return controlnumbers;
}

I believe with Hibernate calling em.lock will actually work.

jsight