如何在(CDI)Bean和外部方式中使用JPA / JTA

时间:2016-08-14 09:42:17

标签: java jsf jpa jta

我有一个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类注入/)?如果我找到一个解决方案,它会破坏我的另一方面的代码。我是正确的方式还是诉讼中的根本错误?

0 个答案:

没有答案