I have a JSF application (Java 8, Wildfly 10, MySQL DB, CDI beans, use of JPA). I got my EntityManager from a self-made static JpaHelper class, it also contains frequently used queries. Everything worked fine, but the amount of MySQL connection exhausted.
I switched to a wildfly managed connection to the database. Now my problems started. Now I inject EntityManager in my beans by:
package controller;
import ...
@ViewScoped
@Named
public class ListCommoditiesController implements Serializable {
private static final long serialVersionUID = 4593863260881355166L;
private int commodityId = 0;
@PersistenceContext(unitName = "PU", type = PersistenceContextType.EXTENDED)
private EntityManager em;
public ListCommoditiesController() {
}
@SuppressWarnings("unchecked")
public List<Commodity> getCommodities() {
List<Commodity> commodities = (List<Commodity>) em.createNamedQuery("Commodity.findAll").getResultList();
return commodities;
}
and switched most of the frequently used queries to namedQueries. Some POJOs, Converter and Helper Classes still use my static JpaHelper, because I cannot inject the EM in there and cannot pass the information before, ie in a JSF converter class:
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (value.isEmpty()) {
return null;
}
Integer id = new Integer(value);
return JpaHelper.getCommodityByID(id);
}
}
If I use
<persistence-unit name="PU" transaction-type="RESOURCE_LOCAL">
I got an error "Transaction is required to perform this operation (either use a transaction or extended persistence context" in my CDI-Beans. There are recommendations to avoid the use of resource_local. But If I use
<persistence-unit name="PU" transaction-type="JTA">
I got an error "Unable to access TransactionManager or UserTransaction to make physical transaction delegate" in my JpaHelper class while creating the EntityManager.
My JpaHelper looks like:
public class JpaHelper {
private static final String PERSISTENCE_UNIT_NAME = "PU";
static public EntityManager getEntityManager() {
EntityManagerFactory fact = Persistence.createEntityManagerFactory(
JpaHelper.PERSISTENCE_UNIT_NAME);
return fact.createEntityManager();
}
public static Commodity getCommodityByID(Integer id) {
if (id != null) {
EntityManager em = JpaHelper.getEntityManager();
try {
return (Commodity) em.find(Commodity.class, id);
} catch (Throwable ex) {
ex.printStackTrace();
} finally {
em.close();
}
}
return null;
}
My persistence.xml looks like:
<?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="PU" transaction-type="JTA">
<jta-data-source>java:jboss/datasources/Hanse</jta-data-source>
<class>model.Commodity</class>
<class>model....</class>
<class>model....</class>
<properties>
<!-- <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform"/> -->
<!-- <property name="hibernate.hbm2ddl.auto" value="update" /> -->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
<!-- <property name="hibernate.show_sql" value="true" /> -->
<property name="hibernate.enable_lazy_load_no_trans" value="true"/>
</properties>
</persistence-unit>
</persistence>
I found out, that there are different strategies like container managed transaction, bean managed transaction and application managed transaction. But I think, I messed up things. How can I create an EntityManager (without injecting/in a not-bean class) with JTA? If I found a solution for one thing, it breaks my code on an other side. Am I on the right way or are the fundamental mistakes in the proceeding?