【问题标题】:Java EntityManager null with @PersistenceContext带有@PersistenceContext 的Java EntityManager null
【发布时间】:2018-02-03 23:33:57
【问题描述】:

我正在使用 Wildfly 10,Jersey,并使用 @Inject 注入依赖项。我有 DAO 和 Service 接口及其在 CustomBinder 中声明的实现。注入效果很好,但 EntityManager 被注入 null 并带有 @PersistenceContext 注释。我正在使用 MySQL,并且数据源测试连接正在工作。

API 休息类

@Path("/account")
public class CuentaServiceRS {

    @Inject
    private ICuentaService cuentaService;

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Cuenta getCuenta() {
        return cuentaService.getCuentas().get(0);       
    }

}

ICuentaService

实现
@Stateless
public class CuentaServiceImpl implements ICuentaService {

    @Inject
    private ICuentaDAO cuentaDAO;

    @Override
    public List<Cuenta> getCuentas() {
        List<Cuenta> cuentas = cuentaDAO.getAllCuentas();
        cuentas;
    }

}

CuentaDAO

实现
@Stateless
public class CuentaDAOImpl implements ICuentaDAO {

    @PersistenceContext(unitName = "altitudePU")
    protected EntityManager em;

    @Override
    public List<Cuenta> getAllCuentas() {
        CriteriaQuery<Cuenta> cq = em.getCriteriaBuilder().createQuery(Cuenta.class);

        /...

        return resultlist;
    }

}

我在 persistence.xml

中的持久性单元
<persistence-unit name="altitudePU">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>java:jboss/datasources/AltitudePU</jta-data-source>
    <class>ar.com.olx.domain.Cuenta</class>
    <properties>
        <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" />
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
    </properties>    
</persistence-unit>

web.xml

上配置的servlet
<servlet>
        <servlet-name>altitudeservlet</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>ar.com.villat.bind.ApplicationJaxRS</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
</servlet>

我的自定义 AplicationJaxRS 扩展自 ResourceConfig

public class ApplicationJaxRS extends ResourceConfig {

    public ApplicationJaxRS(){
        register(new CustomBinder());
        packages(true, "ar.com.olx");
    }

}

CustomBinder

public class CustomBinder extends AbstractBinder {

    @Override
    protected void configure() {
        bind(CuentaServiceImpl.class).to(ICuentaService.class);
        bind(CuentaDAOImpl.class).to(ICuentaDAO.class);
    }

}

最后,我的 pom.xml 与这篇文章相关的依赖项

<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet</artifactId>
    <version>2.22.2</version>
</dependency>

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>javax.enterprise</groupId>
    <artifactId>cdi-api</artifactId>
    <version>1.2</version>
</dependency>

<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <version>7.0</version>
</dependency>

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-annotations</artifactId>
    <version>3.5.6-Final</version>
</dependency>

<dependency>
    <groupId>org.hibernate.javax.persistence</groupId>
    <artifactId>hibernate-jpa-2.1-api</artifactId>
    <version>1.0.0.Final</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>org.jboss.spec.javax.ejb</groupId>
    <artifactId>jboss-ejb-api_3.2_spec</artifactId>
    <version>1.0.0.Final</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.39</version>
</dependency>

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.4</version>
</dependency>

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.5</version>
</dependency>

<dependency>
    <groupId>dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>1.6.1</version>
    <scope>provided</scope>
</dependency>

如果您需要更多信息,请告诉我。

【问题讨论】:

    标签: java maven wildfly entitymanager jta


    【解决方案1】:

    当您使用的是全栈 JavaEE 服务器时,您可以大大简化这一点。

    如果您还没有将 MySQL 数据源添加到 WildFly,那么您可以这样做:

    WildFly 数据源设置

    1. 创建一个名为deploy-mysql-ds.cli 的文件,其内容如下:

      # Execute offline
      embed-server --server-config=standalone.xml
      
      deploy $HOME/.m2/repository/mysql/mysql-connector-java-5.1.39.jar
      
      # Add the application datasource
      data-source add \
          --name=AltitudeDS \
          --driver-name=mysql-connector-java-5.1.39.jar \
          --connection-url=jdbc:mysql://localhost:3306/altitudeDB \
          --jndi-name=java:jboss/datasources/AltitudePU \
          --user-name=$USER_NAME \
          --password=$PASSWORD
      
    2. $HOME$USER_NAME$PASSWORD 替换为实际值

    3. 通过执行如下方式在 Wildfly 中配置数据源:

      $JBOSS_HOME/bin/jboss-cli.sh --file="deploy-mysql-ds.cli"
      

    您只需执行一次。

    请注意,--jndi-name&lt;jta-data-source&gt;...&lt;/jta-data-source&gt; 匹配 你的 persistence.xml 文件。

    你不需要 mysql-connector-java-5.1.39.jar 在你的 maven 依赖项中,因为它已经直接添加到服务器了。还有其他解决方案涉及将 jar 添加为“模块” 但我发现这种方式要简单得多。

    修改申请

    如下修改您的申请:

    1. 移除所有多余的依赖:

      <dependencies>
          <dependency>
              <groupId>javax</groupId>
              <artifactId>javaee-api</artifactId>
              <version>7.0</version>
              <scope>provided</scope>
          </dependency>
          <dependency>
              <groupId>org.apache.commons</groupId>
              <artifactId>commons-lang3</artifactId>
              <version>3.4</version>
          </dependency>
          <dependency>
              <groupId>commons-io</groupId>
              <artifactId>commons-io</artifactId>
              <version>2.5</version>
          </dependency>
      </dependencies>
      
    2. 删除AplicationJaxRSCustomBinder 类并添加JAXRSConfiguration 类:

      /**
       * Configures a JAX-RS endpoint
       */
      @ApplicationPath("resources")
      public class JAXRSConfiguration extends Application {
      }
      
    3. 从 web.xml 中删除 altitudeservlet。如果这是其中唯一的内容,则完全删除整个文件。

    测试一下

    您应该能够部署此 Web 应用程序并从以下位置访问它:

    http://localhost:8080/altitude-webapp/resources/account
    

    altitude-webapp 是您的 WAR 文件的名称。

    【讨论】:

    • 嗨,史蒂夫,有两个问题:我应该在 JAXRSConfiguration 上添加什么?我正在使用 Jersey,这就是我现在有一个 CustomBinder 的原因;如果我删除“altitudeservlet”,我应该如何配置 POJOMapping?谢谢
    • 暂时忘记泽西岛,开始运行吧。我们可以稍后解决这个问题
    • 现在一切正常!只是出于好奇,我必须将 JAXRSConfiguration 留空,或者它对某些配置有用吗?谢谢
    • 这个类经常是空的。了解更多信息的最佳地点是JAX-RS 2.0 Specification 的第 2 节
    猜你喜欢
    • 1970-01-01
    • 2023-03-23
    • 2018-01-20
    • 1970-01-01
    • 2015-09-28
    • 2017-03-20
    • 2011-06-10
    • 2017-05-19
    • 2018-02-10
    相关资源
    最近更新 更多