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

[sourcecode language="java"]
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

[sourcecode language="java"]
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: , , , ,