3
Hello, I am using Tomcat + JPA + Vraptor 4 and I am using cdi to inject Entitymanager as follows.
Entitymanagerfactorycreator:
public class EntityManagerFactoryCreator {
@ApplicationScoped
@Produces
public EntityManagerFactory getEntityManagerFactory(){
return Persistence.createEntityManagerFactory("default");
}
public void destroy(@Disposes EntityManagerFactory factory){
if(factory.isOpen()){
factory.close();
}
}
}
Entitymanagercreator:
public class EntityManagerCreator {
private EntityManagerFactory factory;
/**
* @depreciated CDI eyes only
*/
public EntityManagerCreator() {}
@Inject
public EntityManagerCreator(EntityManagerFactory factory) {
this.factory = factory;
}
@Produces @RequestScoped
public EntityManager getEntityManager(){
return factory.createEntityManager();
}
public void destroy(@Disposes EntityManager entityManager){
if(entityManager.isOpen()){
entityManager.close();
}
}
}
Genericdao:
public abstract class DAO < T > {
/**
* EntityManager
*/
@
Inject private EntityManager em;
/**
* Faz referência aos DAOS
*/
private Class < T > clazz;
public DAO() {
clazz = getClazz();
}
@
Transactional
public boolean create(T entity) {
try {
em.getTransaction().begin();
em.persist(entity);
em.getTransaction().commit();
return true;
} catch (Exception e) {
return false;
}
}
@
Transactional
public boolean update(T entity) {
try {
em.getTransaction().begin();
em.merge(entity);
em.getTransaction().commit();
return true;
} catch (Exception e) {
return false;
}
}
public T getById(Long id) {
return em.find(clazz, id);
}
@
Transactional
public boolean remove(Long id) {
try {
T entity = em.find(clazz, id);
em.getTransaction().begin();
em.remove(entity);
em.getTransaction().commit();
return true;
} catch (Exception e) {
return false;
}
}
public List < T > list() {
try {
return em.createQuery("FROM " + clazz.getName(), clazz).getResultList();
} catch (Exception e) {
return null;
}
}
@
SuppressWarnings("unchecked")
private Class < T > getClazz() {
Class <? > classeDAO = this.getClass();
while (classeDAO.getSuperclass() != DAO.class) {
classeDAO = classeDAO.getSuperclass();
}
ParameterizedType tipo = (ParameterizedType) classeDAO.getGenericSuperclass();
Class < T > clazz = null;
try {
clazz = (Class < T > ) tipo.getActualTypeArguments()[0];
} catch (ClassCastException exception) {
throw exception;
}
return clazz;
}
}`
When the Serverdao class is instantiated in the Controller, the connection is opened and closed normally. However, if you are instantiated in a Quartz Job for example and try to make a list with the list() method, the following error occurs.
19:16:01,662 ERROR [Tasklogger ] Task serverTask was failed java.lang.Nullpointerexception at br.com.serverus.tasks.Servertask.execute(Servertask.java:36) at br.com.serverus.tasks.Servertask$Proxy$$Weldclientproxy.execute(Unknown Source) at br.com.Caelum.vraptor.tasks.jobs.simple.ConcurrentJobWrapper.execute(Concurrentjobwrapper.java:20) at org.quartz.core.JobRunShell.run(Jobrunshell.java:202) at org.quartz.simpl.Simplethreadpool$Workerthread.run(Simplethreadpool.java:573)
If I remove the @Requestscoped property from Entitymanagercreator, the listing works, but the connection is kept open.
If I trigger a cdi event, and use @Inject Serverdao the connection remains open.
How can I close the connection, or use a better approach without the default Opensessioninview?