Java EntityManager 为空,@PersistenceContext

Java EntityManager null with @PersistenceContext

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

API休息class

@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 与此相关的依赖项 post

<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>

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

由于您使用的是全栈 JavaEE 服务器,因此可以大大简化这一过程。

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

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 匹配 <jta-data-source>...</jta-data-source> 你的 persistence.xml 文件。

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

修改申请

修改您的申请如下:

  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 classes 并添加 JAXRSConfiguration class:

    /**
     * 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 文件的名称。