Skip to content

Instantly share code, notes, and snippets.

@justinwyer
Created July 8, 2012 16:27
Show Gist options
  • Save justinwyer/3071648 to your computer and use it in GitHub Desktop.
Save justinwyer/3071648 to your computer and use it in GitHub Desktop.
Java EE 6 Web Profile Without the App Server. Part 3.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
<interceptors>
<class>com.lifeasageek.goodstuffexample.cdi.TransactionInterceptor</class>
<class>com.lifeasageek.goodstuffexample.cdi.GoodInterceptor</class>
</interceptors>
</beans>
@Entity
public class Deed implements Serializable
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column
private String altruist;
@Column
private String recipient;
public Deed()
{
}
public Deed(String altruist, String recipient)
{
this.altruist = altruist;
this.recipient = recipient;
}
// Getters and setters...
}
@ApplicationScoped
public class EntityManagerProducer
{
private static EntityManagerFactory emf;
private static ThreadLocal<Stack<EntityManager>> threadEntityManagers = new ThreadLocal<>();
public void register(boolean requireNew)
{
if (emf == null)
{
emf = Persistence.createEntityManagerFactory("goodstuff");
}
if (threadEntityManagers.get() == null)
{
threadEntityManagers.set(new Stack<EntityManager>());
}
Stack<EntityManager> emStack = threadEntityManagers.get();
if (emStack.isEmpty())
{
emStack.push(emf.createEntityManager());
}
else
{
EntityManager em = emStack.peek();
EntityTransaction tx = em.getTransaction();
if (tx.isActive() && requireNew)
{
emStack.push(emf.createEntityManager());
}
}
}
public EntityManager get()
{
Stack<EntityManager> emStack = threadEntityManagers.get();
if (emStack == null || emStack.isEmpty())
{
register(false);
emStack = threadEntityManagers.get();
}
EntityManager em = emStack.peek();
return em;
}
public void unregister(EntityManager em)
{
Stack<EntityManager> emStack = threadEntityManagers.get();
emStack.remove(em);
}
}
public class EntityManagerWrapper implements EntityManager
{
@Inject
private EntityManagerProducer emp;
@Override
public void persist(Object entity)
{
emp.get().persist(entity);
}
// All methods wrapped.
}
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="goodstuff" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:goodstuff"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.show_sql" value="false"/>
</properties>
</persistence-unit>
</persistence>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.0.0.Final</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.3.160</version>
</dependency>
@InterceptorBinding
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Transactional
{
}
@Transactional
@Interceptor
public class TransactionInterceptor
{
@Inject
private EntityManagerProducer emp;
private boolean owner = false;
private EntityTransaction tx;
@AroundInvoke
public Object manageTransaction(InvocationContext ctx) throws Exception
{
emp.register(false);
EntityManager em = emp.get();
em.setFlushMode(FlushModeType.COMMIT);
tx = em.getTransaction();
try
{
if (!tx.isActive())
{
tx.begin();
owner = true;
}
Object result = ctx.proceed();
if (tx.isActive() && owner)
{
tx.commit();
}
return result;
}
catch (Exception ex)
{
if (tx.isActive() && !owner)
{
tx.setRollbackOnly();
}
if (tx.isActive() && owner)
{
tx.rollback();
}
throw ex;
}
finally
{
try
{
if (tx.isActive() && tx.getRollbackOnly() && owner)
{
tx.rollback();
}
}
catch (Exception ex)
{
// Something is horribly wrong!
ex.printStackTrace();
}
finally
{
if (owner)
{
emp.unregister(em);
em.close();
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment