【问题标题】:JPA EntityManager not initialized in struts2 and JBOSS 7.1JPA EntityManager 未在 struts2 和 JBOSS 7.1 中初始化
【发布时间】:2014-11-24 05:10:32
【问题描述】:

我正在使用 Jboss 提供的 JPA 库启动基于 struts2 的应用程序。 我已经在standalone.xml 中配置了数据源我可以从jboss 管理控制台看到 数据源已创建。并读取和处理 presistence.xml 文件。 但是,如果我检查 Action Class 中的 EntityManager 实例。它总是说 null。

这是我的 persistence.xml 和 Action 类 sn-p

<?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="primary">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <jta-data-source>java:jboss/datasources/mysqlDS</jta-data-source>

        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>
            <!-- Properties for Hibernate -->
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
            <property name="hibernate.use_sql_comments" value="true" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
        </properties>

    </persistence-unit>

</persistence>

Struts2 动作类:

public class RegistrationAction extends  ActionSupport implements SessionAware,Preparable ,ModelDriven{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @PersistenceContext(unitName="primary")
    private EntityManager em;

    @Override
    public Object getModel() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void prepare() throws Exception {
        if(em==null)
            System.out.println(" EM is null still..");
         //even Persistence.createEntityManagerFactory("primary"); returning NULL

    }

    @Override
    public void setSession(Map<String, Object> arg0) {
        // TODO Auto-generated method stub

    }

    public EntityManager getEm() {
        return em;
    }

    public void setEm(EntityManager em) {
        this.em = em;
    }

}

【问题讨论】:

  • 一些建议,因为我不知道确切的答案。您使用的是容器还是 bean 管理的持久性?如果是 CMT,那么您是否尝试过注入 entityManagerFactory 而不是 entityManager?
  • 我没有使用 EJB。它适用于 Web 组件吗?
  • 是的,确实如此。就像最初的建议一样,尝试注入 entityManagerFactory 而不是 entityManager。你可以谷歌了解如何做到这一点。如果您得到不同的答案,请先尝试他们的方法,因为我不太确定 entityManagerFactory 的附加值。
  • 尝试注入 EMF 但仍然是同样的问题。这与 struts2 的名气有关..因为我写了简单的 servlet 并尝试注入 EM,它工作正常。如果我通过 strut2 调度程序或其他东西,它不起作用..

标签: java jpa struts2 jboss7.x cdi


【解决方案1】:

动作由 Struts Container 管理。

EntityManager 由 CDI 容器 管理。您可以将其注入 CDI 托管对象(EJB 容器中的 EJB、CDI 托管 bean、servlet、ecc...),但不能注入到操作中。

您需要使用Struts2-CDI-Plugin 或执行查找来获取它。顺便说一句,您甚至不应该将其注入到 Actions 中,最好使用业务组件(例如 EJB)并对其执行查找。

如果不使用 CDI 插件(例如因为使用 Spring 插件),Rob Veldpaus 的 CDIUtil.java 非常适合。

EJB 示例:

@Stateless
public class MyEjb{

    @PersistenceContext(unitName="primary")
    EntityManager em;

    public Foo find(long id){
        return em.find(Foo.class, id);
    }
}

示例操作:

public class RegistrationAction extends ActionSupport 
                             implements SessionAware,Preparable ,ModelDriven {

    public String execute(){
        MyEjb ejb = new CdiUtil().lookup(MyEjb.class);
        System.out.println(ejb.find(1L));
        return SUCCESS;
    }

    /* your other stuff here */
}

【讨论】:

  • 很好..但我还有另一个问题。我尝试使用 em.persit() 保存模型。它说:JBAS011469:执行此操作需要事务(使用事务或扩展持久性上下文)..如果我尝试调用 em.getTransaction() 是说 EntityManager不能使用交易..有什么建议吗?我已经有 @PersistenceContext(unitName="primary",type=PersistenceContextType.TRANSACTION) 了。
  • 您需要在 EJB(事务默认由容器管理)或 CDI 组件(通过手动处理事务或使用 @Interceptor)中执行此操作,或者如果您愿意要在视图层 (Actions) 中执行此操作,您需要使用 OSIV (Open Session In View, with Hibernate) / OEMIV (Open Entity Manager In View, with JPA) anti-pattern。我强烈建议使用 EJB 3.1 方式。
  • 我正在为一家公司编写工作门户。我正在考虑切换到 Tomcat7 -EclipseLink 。我认为我不需要 EJB 和 Jboss 提供的其他服务。你说什么?对不起,这是题外话..
  • 您可以按照 BalusC 的博客文章中的说明在 Tomcat 中安装 Weld (reference CDI implementation) or OpenWebBeans (Apache CDI implementation),或者干脆使用 TomEE (Tomcat on steroids),我从来没有听到任何人在任何地方说它的坏话。如果您想要开箱即用的 EclipseLink,您需要 TomEE PluME
【解决方案2】:

CDI Plugin struts 2 插件为我工作。

pom.xml 包含在:

    <!-- Import the CDI API -->
    <dependency>
        <groupId>org.apache.struts</groupId>
        <artifactId>struts2-cdi-plugin</artifactId>
        <version>${struts2.version}</version>
    </dependency>
    <dependency>
        <groupId>javax.enterprise</groupId>
        <artifactId>cdi-api</artifactId>
        <version>1.0-SP1</version><!--$NO-MVN-MAN-VER$-->
        <scope>provided</scope>
    </dependency>

然后在我的 Action 类中:

public class SampleAction extends BaseAction{

private static final long serialVersionUID = 1L;

@PersistenceUnit
private EntityManagerFactory emf;

@Action(value="add")
public String add(){
    try{
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        ........
        em.merge(...);
        em.getTransaction().commit();
    }catch(Exception e){
        e.printStackTrace();
    }
    return SUCCESS;
}
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-17
    • 2010-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-23
    相关资源
    最近更新 更多