【问题标题】:EntityManager returning always nullEntityManager 总是返回 null
【发布时间】:2015-10-15 00:26:42
【问题描述】:

每次我请求 entityManager 时它都为空,请参阅:

@Named
@ApplicationScoped
@AnBasicDAO
public class BasicDAOImpl implements BasicDAO, Serializable {

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

    @PersistenceContext(unitName="generalPU")
    protected EntityManager entityManager;

这是我的 persistence.xml:

<persistence-unit name="generalPU" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>     
        <non-jta-data-source>java:/comp/env/jdbc/testeDS</non-jta-data-source>
        <properties>
            <property name="hibernate.show_sql" value="false" />
            <property name="hibernate.format_sql" value="false" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
            <property name="hibernate.cache.use_second_level_cache"
                value="false" />
            <property name="hibernate.cache.use_query_cache" value="false" />
            <property name="hibernate.jdbc.batch_size" value="50" />            
        </properties>
    </persistence-unit>

这是我在 server.xml (tomcat) 中的资源:

<Context docBase="/home/usertest/Programas/apache-tomcat-7.0.59/webapps/cardoso" path="/cardoso" reloadable="false" source="org.eclipse.jst.jee.server:cardoso">
 <Resource name="jdbc/testeDS" auth="Container" type="javax.sql.DataSource"
          username="postgres"
          password="pgadmin"
          driverClassName="org.postgresql.Driver"
          url="jdbc:postgresql://localhost:5432/teste"
          maxTotal="25"
          maxIdle="10"
          validationQuery="select 1" />

</Context>

我的 context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<Context>
  <ResourceLink global="jdbc/sabrecadoDS" name="jdbc/testeDS" type="javax.sql.DataSource"/>
   <Manager pathname=""/> <!-- disables storage of sessions across restarts -->
   <Resource name="BeanManager"
      auth="Container"
      type="javax.enterprise.inject.spi.BeanManager"
      factory="org.jboss.weld.resources.ManagerObjectFactory"/>
</Context>

有什么问题吗? EntityManager 始终为空。前段时间我使用了 Spring(现在是 CDI)并在 applicationContext 中定义了并正常工作。

【问题讨论】:

  • 您如何获得对您的BasicDAOImpl 的引用?
  • 对不起,我没有理解你的问题。
  • CDI 在 tomcat 中无法开箱即用。您需要一个 JavaEE 应用程序服务器,例如 TomEE 或 Glassfish。使用 tomcat,需要使用独立的 CDI 容器,例如 Weld。
  • 我使用 Weld 作为 CDI 实现

标签: java tomcat cdi


【解决方案1】:

CDI 不理解 @PersistenceContext。所以改成:

@Inject
protected EntityManager entityManager;

但是你必须在某个地方定义EntityManager,比如说:

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import org.apache.deltaspike.jpa.api.transaction.TransactionScoped;

public class CdiApplicationConfig {

    @Inject
    private EntityManagerFactory emf;

    @Produces
    @ApplicationScoped
    public EntityManagerFactory createEntityManagerFactory() {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("generalPU");
        return emf;
    }

    public void close(@Disposes EntityManagerFactory emf) {
        emf.close();
    }

    @Produces
    @TransactionScoped // is a bit better than @RequestScoped because it won't allow perform injection outside transaction context
    public EntityManager createEntityManager() {
        return emf.createEntityManager();
    }

    public void close(@Disposes EntityManager em) {
        if (em.isOpen()) {
            em.close();
        }
    }
}

以上代码使用DeltaSpike 进行事务管理 - 但您可以使用任何您想要的东西。

另一个提示:我不确定persistence.xml 中引用的数据源名称中的java:/comp 之间是否允许使用斜线,因此请同时检查:

  <non-jta-data-source>java:comp/env/jdbc/testeDS</non-jta-data-source>

如您所见,CDI 与 Spring 非常相似。

【讨论】:

  • CDI 如何知道应该在注入 ENtityManager 属性时调用 createEntityManagerFactory() ?
  • 在 EE-Server 中,您仍然可以使用 @PersistenceContext 以及来自(和用于)OpenWebBeans 的资源模块。
  • 为什么这只能在 EE-Server 中工作? EE-Server 更常用的是什么?
  • @DarWhi 是的,但是这篇文章显然是关于 Tomcat + Weld,所以我们不在资源匮乏的 Java EE 服务器之外。
  • @Scientist @PersistenceContext 可以在 Java EE 服务器中工作,因为它们必须遵守此注解。 CDI 更简单。它只知道如何注入之前用@Produces 声明过的bean。简而言之:CDI 查看此类 Producer 方法的返回类型。要获取详细信息,请阅读CDI doc
猜你喜欢
  • 2021-09-21
  • 1970-01-01
  • 2014-03-04
  • 2016-11-02
  • 2014-05-06
  • 2012-06-05
  • 2014-05-30
  • 2014-02-23
  • 2017-10-12
相关资源
最近更新 更多