java.lang.IllegalArgumentException:WFLYWELD0037:将持久性单元注入 CDI 托管 bean 时出错
java.lang.IllegalArgumentException: WFLYWELD0037: Error injecting persistence unit into CDI managed bean
我看到的错误与 here 中记录的错误类似。但是,我的 EAR 和 WAR 项目之间没有直接的 ejb 注入。
环境:
应用程序服务器:JBoss EAP 7.3
我将项目设置为:
EJB-EAR:
- 包含一个 DataManagement.jar,其中包含所有 DAO 对象、JPA 相关内容和 persistence.xml
- persistence.xml 位于 jar
中的 main/resources/META-INF/ 下
persistence.xml:
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="primary">
<!-- If you are running in a production environment, add a managed
data source, this example data source is just for development and testing! -->
<jta-data-source>java:jboss/datasources/PcosDS</jta-data-source>
<properties>
<!-- Properties for Hibernate -->
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.show_sql" value="false" />
</properties>
</persistence-unit>
</persistence>
一个示例 DAO 对象看起来像
@Stateless
public class LoginAttemptDAO {
private static final ILogger logger = LoggerFactory
.getLogger(LoginAttemptDAO.class);
@Inject
private EntityManager entityManager;
生产者定义为:
public class Resources {
@Produces
@PersistenceContext(unitName="primary")
private EntityManager em;
}
WAR:
- WAR 项目启动应用程序并在其 WEB-INF/lib 中包含其他 jar。这些 jar 之一最终通过 EJB 查找访问 EAR 项目中的 jar。
- WAR 包含 jboss-deployment-structure.xml 和 /src/main/webapp/META-INF
下的 jboss-all.xml
jboss-部署-structure.xml
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
<dependencies>
<module name="deployment.pts-ear-1.0-SNAPSHOT.ear.DataManagement.jar"/>
</dependencies>
<exclusions>
</exclusions>
</deployment>
</jboss-deployment-structure>
jboss-all.xml
<jboss umlns="urn:jboss:1.0">
<jboss-deployment-dependencies xmlns="urn:jboss:deployment-dependencies:1.0">
<dependency name="pts-ear-1.0-SNAPSHOT.ear" />
</jboss-deployment-dependencies>
</jboss>
EAR 部署良好,我确实看到测试数据库预先填充了初始数据。我一部署 war 项目就会出现问题,我看到的错误是
Caused by: java.lang.IllegalArgumentException: WFLYWELD0037: Error
injecting persistence unit into CDI managed bean. Can't find a
persistence unit named 'primary' in deployment
InitializeServlet-war-1.0-SNAPSHOT.war for injection point private
javax.persistence.EntityManager
com.lmco.pts.pcos.inf.DataManagement.dao.Resources.em
at org.jboss.as.weld.jpa@7.3.0.GA-redhat-00004//org.jboss.as.weld.services.bootstrap.WeldJpaInjectionServices.getScopedPUName(WeldJpaInjectionServices.java:105)
at org.jboss.as.weld.jpa@7.3.0.GA-redhat-00004//org.jboss.as.weld.services.bootstrap.WeldJpaInjectionServices.registerPersistenceContextInjectionPoint(WeldJpaInjectionServices.java:68)
at org.jboss.weld.core@3.1.2.Final-redhat-00001//org.jboss.weld.injection.ResourceInjectionFactory$PersistenceContextResourceInjectionProcessor.getResourceReferenceFactory(ResourceInjectionFactory.java:174)
at org.jboss.weld.core@3.1.2.Final-redhat-00001//org.jboss.weld.injection.ResourceInjectionFactory$PersistenceContextResourceInjectionProcessor.getResourceReferenceFactory(ResourceInjectionFactory.java:162)
如果我将 DataManagement.jar 打包到 WAR 项目的 WEB-INF/lib 中,一切正常。我正在尝试将 DataManagement.jar 移出 war 项目,以便它可以被其他项目使用,并作为部署在应用程序服务器上的其他项目的动态资源。我怀疑持久性单元在某种程度上对 WAR 不可见,但 WAR 并不真正需要持久性单元。它只是从执行数据库访问的 JAR 调用服务。
如果我没理解错的话,您是在假设一个单独的 JAR 是您可以直接引用的专用部署,但事实并非如此。持久性单元必须是部署的一部分。也许可以为 JAR 创建一个 JBoss 模块并引用它,但最后,它将为引用该模块的每个部署启动持久性单元。将那个 JAR 放入 WEB-INF/lib 有什么问题?您也可以将 JAR 打包到其他 WAR 中。
原来我没有 post 的缺失信息之一是 DataManagement.jar 的 beans.xml 配置。它的 bean 发现模式设置为全部以允许未注释的生产者 class 发现资源:
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="all">
</beans>
删除此文件后(最新的 CDI 不需要此文件,默认情况下 bean 发现模式设置为注释)或将发现模式更改为“注释”并将生产者 class 注释为:
@Stateless
public class Resources {
@PersistenceContext(unitName="primary")
private EntityManager em;
@Produces
public EntityManager entityManager(){
return em;
}
}
部署的 WAR 能够通过执行 ejb 查找成功访问 DataManagement.jar。
我看到的错误与 here 中记录的错误类似。但是,我的 EAR 和 WAR 项目之间没有直接的 ejb 注入。
环境: 应用程序服务器:JBoss EAP 7.3
我将项目设置为: EJB-EAR:
- 包含一个 DataManagement.jar,其中包含所有 DAO 对象、JPA 相关内容和 persistence.xml
- persistence.xml 位于 jar 中的 main/resources/META-INF/ 下
persistence.xml:
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="primary">
<!-- If you are running in a production environment, add a managed
data source, this example data source is just for development and testing! -->
<jta-data-source>java:jboss/datasources/PcosDS</jta-data-source>
<properties>
<!-- Properties for Hibernate -->
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.show_sql" value="false" />
</properties>
</persistence-unit>
</persistence>
一个示例 DAO 对象看起来像
@Stateless
public class LoginAttemptDAO {
private static final ILogger logger = LoggerFactory
.getLogger(LoginAttemptDAO.class);
@Inject
private EntityManager entityManager;
生产者定义为:
public class Resources {
@Produces
@PersistenceContext(unitName="primary")
private EntityManager em;
}
WAR:
- WAR 项目启动应用程序并在其 WEB-INF/lib 中包含其他 jar。这些 jar 之一最终通过 EJB 查找访问 EAR 项目中的 jar。
- WAR 包含 jboss-deployment-structure.xml 和 /src/main/webapp/META-INF 下的 jboss-all.xml
jboss-部署-structure.xml
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
<dependencies>
<module name="deployment.pts-ear-1.0-SNAPSHOT.ear.DataManagement.jar"/>
</dependencies>
<exclusions>
</exclusions>
</deployment>
</jboss-deployment-structure>
jboss-all.xml
<jboss umlns="urn:jboss:1.0">
<jboss-deployment-dependencies xmlns="urn:jboss:deployment-dependencies:1.0">
<dependency name="pts-ear-1.0-SNAPSHOT.ear" />
</jboss-deployment-dependencies>
</jboss>
EAR 部署良好,我确实看到测试数据库预先填充了初始数据。我一部署 war 项目就会出现问题,我看到的错误是
Caused by: java.lang.IllegalArgumentException: WFLYWELD0037: Error injecting persistence unit into CDI managed bean. Can't find a persistence unit named 'primary' in deployment InitializeServlet-war-1.0-SNAPSHOT.war for injection point private javax.persistence.EntityManager com.lmco.pts.pcos.inf.DataManagement.dao.Resources.em at org.jboss.as.weld.jpa@7.3.0.GA-redhat-00004//org.jboss.as.weld.services.bootstrap.WeldJpaInjectionServices.getScopedPUName(WeldJpaInjectionServices.java:105) at org.jboss.as.weld.jpa@7.3.0.GA-redhat-00004//org.jboss.as.weld.services.bootstrap.WeldJpaInjectionServices.registerPersistenceContextInjectionPoint(WeldJpaInjectionServices.java:68) at org.jboss.weld.core@3.1.2.Final-redhat-00001//org.jboss.weld.injection.ResourceInjectionFactory$PersistenceContextResourceInjectionProcessor.getResourceReferenceFactory(ResourceInjectionFactory.java:174) at org.jboss.weld.core@3.1.2.Final-redhat-00001//org.jboss.weld.injection.ResourceInjectionFactory$PersistenceContextResourceInjectionProcessor.getResourceReferenceFactory(ResourceInjectionFactory.java:162)
如果我将 DataManagement.jar 打包到 WAR 项目的 WEB-INF/lib 中,一切正常。我正在尝试将 DataManagement.jar 移出 war 项目,以便它可以被其他项目使用,并作为部署在应用程序服务器上的其他项目的动态资源。我怀疑持久性单元在某种程度上对 WAR 不可见,但 WAR 并不真正需要持久性单元。它只是从执行数据库访问的 JAR 调用服务。
如果我没理解错的话,您是在假设一个单独的 JAR 是您可以直接引用的专用部署,但事实并非如此。持久性单元必须是部署的一部分。也许可以为 JAR 创建一个 JBoss 模块并引用它,但最后,它将为引用该模块的每个部署启动持久性单元。将那个 JAR 放入 WEB-INF/lib 有什么问题?您也可以将 JAR 打包到其他 WAR 中。
原来我没有 post 的缺失信息之一是 DataManagement.jar 的 beans.xml 配置。它的 bean 发现模式设置为全部以允许未注释的生产者 class 发现资源:
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="all">
</beans>
删除此文件后(最新的 CDI 不需要此文件,默认情况下 bean 发现模式设置为注释)或将发现模式更改为“注释”并将生产者 class 注释为:
@Stateless
public class Resources {
@PersistenceContext(unitName="primary")
private EntityManager em;
@Produces
public EntityManager entityManager(){
return em;
}
}
部署的 WAR 能够通过执行 ejb 查找成功访问 DataManagement.jar。