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 数据源设置
创建一个名为 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
用真实值替换$HOME
、$USER_NAME
和$PASSWORD
通过如下方式在 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"
但我发现这种方式要简单得多。
修改申请
修改您的申请如下:
删除所有多余的依赖:
<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>
删除 AplicationJaxRS
和 CustomBinder
classes 并添加 JAXRSConfiguration
class:
/**
* Configures a JAX-RS endpoint
*/
@ApplicationPath("resources")
public class JAXRSConfiguration extends Application {
}
从 web.xml 中删除 altitudeservlet
。如果这是其中唯一的内容,则完全删除整个文件。
测试一下
您应该能够部署此 Web 应用程序并从以下位置访问它:
http://localhost:8080/altitude-webapp/resources/account
其中 altitude-webapp
是您的 WAR 文件的名称。
我正在使用 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 数据源设置
创建一个名为
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
用真实值替换
$HOME
、$USER_NAME
和$PASSWORD
通过如下方式在 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" 但我发现这种方式要简单得多。
修改申请
修改您的申请如下:
删除所有多余的依赖:
<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>
删除
AplicationJaxRS
和CustomBinder
classes 并添加JAXRSConfiguration
class:/** * Configures a JAX-RS endpoint */ @ApplicationPath("resources") public class JAXRSConfiguration extends Application { }
从 web.xml 中删除
altitudeservlet
。如果这是其中唯一的内容,则完全删除整个文件。
测试一下
您应该能够部署此 Web 应用程序并从以下位置访问它:
http://localhost:8080/altitude-webapp/resources/account
其中 altitude-webapp
是您的 WAR 文件的名称。