Adam Bien's Weblog

EJB: How To Catch javax.persistence.OptimisticLockException

Exceptions like javax.persistence.OptimisticLockException may occur at commit time and so after the execution of an EJB method. Therefore some occurrences are impossible to catch with the convenient "Container Managed Transactions" configuration.

The method DataStore#update fails, because SomeEntity changes are going to be recognized at commit time and so after the execution of this method.

public class DataStore {

    EntityManager em;

    public void update(String id) {
        SomeEntity forUpdate = this.em.find(SomeEntity.class, id);


The exception: "javax.ejb.EJBException: Transaction marked for rollback" is raised after the execution of the EJB and can be only caught in the presentation layer.

However, transactions can be started and committed, and so handled, in an interceptor:

public class TXEnforcer {

    UserTransaction tx;
    private final static Logger LOG = Logger.getLogger(TXEnforcer.class.getName());

    public Object beginAndCommit(InvocationContext ic) throws Exception {
        try {
            Object retVal = ic.proceed();
            return retVal;
        } catch (RollbackException e) {
            LOG.severe("-----------------Caught (in interceptor): " + e.getCause());
            throw e;
        } catch (RuntimeException e) {
            throw e;


The EJB needs to use the TXEnforcer interceptor to handle transactions and has to switch to the "Bean Managed Transactions" strategy (otherwise you get a: Caused by: javax.naming.NameNotFoundException: Lookup of java:comp/UserTransaction not allowed for Container managed Transaction beans):

public class DataStore {

In this example the DataStore EJB is a boundary which always initiates a new transaction. Therefore there is no need to handle existing transactions.

Thanks Marian S. for asking the question!

[See also Boundary pattern in the "Real World Java EE Patterns--Rethinking Best Practices" book (Second Iteration, "Green Book"), page 57 in, chapter "Boundary"]

The project catchemall was checked in into

See you at Java EE Workshops at MUC Airport (Effective + Architectures -- usually transactions are heavily discussed at these days)!

NEW online workshop: WebStandards Igniter (online)

Airport MUC workshops: Java EE 7: Bootstrap, Effective, Architectures, Web, React and Angular, Testing and Microservices


A book about rethinking Java EE Patterns


Interesting and pragmatic approach, but what about a generic retry mechanism? I think it's legal to handle OptimisticLockException just by giving the transaction at least one more try by automatism...

Posted by Jonny Newald on May 28, 2013 at 09:31 PM CEST #


thanks for your comment! I answered it with a new post:


Posted by Adam Bien on May 30, 2013 at 08:48 PM CEST #

If rest services are used it is more comfortable to write a servlet filter and catch/map these exceptions there.

Imho more readable and easier. I used this trick in my game.


Posted by Markus on June 02, 2013 at 03:25 PM CEST #

Hi Adam,

What about invoking em.flush() inside interceptor?
I never tried and just coming out of my head just now.


Posted by Rock Ching on November 13, 2013 at 09:24 AM CET #


I am currently using em.flush inside the interceptor and it works greatly.

My only concern is about performance: I recently discovered that Hibernate implements dirty checking without tracking setter, so it just check the state of every entity associated with the persistence context. Given this, a flush would cause a complete check of all entities, and the successive commit outside the interceptor would cause another check.

If this is true, I would say it's better to call em.clear() just after em.flush().

I would like to hear something by an expert like Adam Bien ;)

Posted by Alberto Gori on March 04, 2014 at 11:49 AM CET #

Post a Comment:
  • HTML Syntax: NOT allowed
Online Workshops
...the last 150 posts
...the last 10 comments