我有一个JSF应用程序(Java 8,Wildfly 10,MySQL DB,CDI bean,JPA的使用)。我从一个自制的静态JpaHelper类中获取了我的EntityManager,它还包含常用的查询。一切正常,但MySQL连接数量已经耗尽。
我切换到了数据库的wildfly托管连接。现在我的问题开始了。现在我通过以下方式在我的bean中注入EntityManager:
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;
}
并将大多数常用查询切换为namedQueries。一些POJO,转换器和帮助程序类仍然使用我的静态JpaHelper,因为我不能在那里注入EM并且之前无法传递信息,即在JSF转换器类中:
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (value.isEmpty()) {
return null;
}
Integer id = new Integer(value);
return JpaHelper.getCommodityByID(id);
}
}
如果我使用
<persistence-unit name="PU" transaction-type="RESOURCE_LOCAL">
我收到错误“需要事务来执行此操作(在我的CDI-Beans中使用事务或扩展持久化上下文”。有建议避免使用resource_local。但如果我使用
<persistence-unit name="PU" transaction-type="JTA">
在创建EntityManager时,我在JpaHelper类中收到错误“无法访问TransactionManager或UserTransaction以进行物理事务委托”。
我的JpaHelper看起来像:
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;
}
我的persistence.xml看起来像:
<?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>
我发现,有不同的策略,如容器管理事务,bean管理事务和应用程序管理事务。但我想,我搞砸了。如何使用JTA创建EntityManager(不使用非bean类注入/)?如果我找到一个解决方案,它会破坏我的另一方面的代码。我是正确的方式还是诉讼中的根本错误?