JPA Transactional Proxy for JavaSE

When using JPA in Java SE, it would still be helpful if a proxy would take care of the transactions and EntityManager life-cycle. I have created such a proxy for my Java/JPA and thought that perhaps others would like to use it as well.

Here is some client code using it

Foo f = JPAUtil.getTransactionalProxy(Foo.class);;

<p>The <code>bar</code> method can then be implemented like this</p>
<pre lang="java" escaped="true">
public void bar(){
  EntityManager em = JPAUtil.getEntityManager();

The JPAUtil

is used to create the proxy and to obtain the EntityManager. The proxy is created using javassist

It creates an JPA transactional proxy with following semantics:

  • Shares an EntityManager per thread
  • Opens and closes the entityManager for each method call
  • Transaction follow REQUIRED pattern (will join an existing transaction)
  • Uses the rollback only flag on the Transaction object
  • Rolls-back on «any» exception

This implementation does not inject the EntityManager into the target object

public class JPAUtil {
  private static Logger logger = LoggerFactory.getLogger(JPAUtil.class);
  static final EntityManagerFactory emf;

  static {
    emf = Persistence.createEntityManagerFactory("manager1");

  private static ThreadLocal&lt;EntityManager> entityManagerThreadLocal = new ThreadLocal&lt;EntityManager>();

  public static EntityManager getEntityManager() {
    EntityManager entityManager = entityManagerThreadLocal.get();
    if (entityManager == null) {
      entityManager = emf.createEntityManager();
    return entityManager;


  public static &lt;T> T getTransactionalProxy(Class&lt;? extends T> clazz) {
    ProxyFactory f = new ProxyFactory();
    f.setFilter(new MethodFilter() {

      public boolean isHandled(Method m) {
        return Modifier.isPublic(m.getModifiers());
    Class c = f.createClass();
    MethodHandler mi = new MethodHandler() {

         public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable {
                final EntityManager entityManager = getEntityManager();
                boolean needToClose = true;
                try {
                    final EntityTransaction transaction = entityManager.getTransaction();
                    boolean iOwnTransaction = !transaction.isActive();
                    needToClose = iOwnTransaction;
                    if (iOwnTransaction) {
                    Object returnValue = null;
                    try {
                        returnValue = proceed.invoke(self, args);
                        if (iOwnTransaction) {
                            if (transaction.getRollbackOnly()) {
                      "Rolling back transaction, as flag has been set");
                            } else
                    } catch (InvocationTargetException e) {

                        if (iOwnTransaction) {
                  "Rolled back transaction due to exception", e);
                        } else {
                  "Setting rollback-only flag due to exception", e);
                        throw e.getTargetException();
                    return returnValue;
                } finally {

                    if (needToClose && entityManager.isOpen()) {


    final T instance;
    try {
      instance = (T) c.newInstance();
      ((ProxyObject) instance).setHandler(mi);
      return instance;
    } catch (InstantiationException e) {
      throw new RuntimeException(e);
    } catch (IllegalAccessException e) {
      throw new RuntimeException(e);



Be Sociable, Share!
On November 3rd, 2011, posted in: JAVA (EE and SE) by Tags: , , , ,