package org.deephacks.westty.internal.jpa; import org.deephacks.westty.jpa.Transactional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.inject.Inject; import javax.interceptor.AroundInvoke; import javax.interceptor.Interceptor; import javax.interceptor.InvocationContext; import javax.persistence.EntityManager; import java.io.Serializable; import java.util.concurrent.Callable; @Transactional @Interceptor class TransactionInterceptor implements Serializable { private static final Logger log = LoggerFactory.getLogger(TransactionInterceptor.class); private static final long serialVersionUID = -1033443722024614083L; @Inject private EntityManagerProducer producer; @AroundInvoke public Object aroundInvoke(final InvocationContext ic) throws Exception { return executeInTx(new Callable<Object>() { @Override public Object call() throws Exception { return ic.proceed(); } }); } public Object executeInTx(Callable<?> future) throws Exception { EntityManager em = producer.createEntityManager(); Object result = null; try { em.getTransaction().begin(); result = future.call(); if (em.getTransaction().isActive()) { em.getTransaction().commit(); } } catch (Exception e) { try { if (em.getTransaction().isActive()) { em.getTransaction().rollback(); } } catch (Exception e1) { log.error("Error rolling back tx. ", e1); } throw e; } finally { if (em != null) { producer.removeEntityManager(); if (em.isOpen()) { em.close(); } } } return result; } }