这个问题完全基于this question。
我使用Hibernate 5.1.0 final / Weld 2.3.2 final在WildFly 10.0.0 final中创建了一个sendbox Java EE应用程序。该项目除了单个实体类,实体监听器和一个普通的空白本地无状态会话bean之外什么也没有 - 没有复杂性,也没有额外的依赖性。
它是由Apache Ant构建和部署的标准NetBeans项目。因此,它不使用Apache Maven。
实体监听器已在/META-INF/orm.xml
中注册。
<entity-mappings version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm http://xmlns.jcp.org/xml/ns/persistence/orm_2_1.xsd">
<entity class="entity.Discount">
<entity-listeners>
<entity-listener class="entity.listener.DiscountListener"/>
</entity-listeners>
</entity>
</entity-mappings>
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="Test-ejbPU" transaction-type="JTA">
<jta-data-source>java:jboss/datasources/datasource</jta-data-source>
<mapping-file>META-INF/orm.xml</mapping-file>
<class>entity.Discount</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
</persistence-unit>
</persistence>
本地无状态会话bean完全空白(不包含任何内容,甚至不包含任何一行)。
@Stateless
public class TestBean implements TestService {
}
实体侦听器包含上述无状态会话bean的注入点(也未编码)。
public class DiscountListener {
@Inject
private TestService service;
@PostPersist
public void postPersist() {
}
}
部署过程突然终止,但出现以下异常。
20:17:54,656 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 116) MSC000001: Failed to start service jboss.persistenceunit."Test.ear/Test-ejb.jar#Test-ejbPU": org.jboss.msc.service.StartException in service jboss.persistenceunit."Test.ear/Test-ejb.jar#Test-ejbPU": javax.persistence.PersistenceException: [PersistenceUnit: Test-ejbPU] Unable to build Hibernate SessionFactory
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:172)
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:117)
at org.wildfly.security.manager.WildFlySecurityManager.doChecked(WildFlySecurityManager.java:667)
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1.run(PersistenceUnitServiceImpl.java:182)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
at org.jboss.threads.JBossThread.run(JBossThread.java:320)
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: Test-ejbPU] Unable to build Hibernate SessionFactory
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:954)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:884)
at org.jboss.as.jpa.hibernate5.TwoPhaseBootstrapImpl.build(TwoPhaseBootstrapImpl.java:44)
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:154)
... 7 more
Caused by: org.jboss.weld.exceptions.IllegalArgumentException: WELD-001456: Argument resolvedBean must not be null
at org.jboss.weld.util.Preconditions.checkArgumentNotNull(Preconditions.java:40)
at org.jboss.weld.manager.BeanManagerImpl.getInjectableReference(BeanManagerImpl.java:794)
at org.jboss.weld.injection.FieldInjectionPoint.inject(FieldInjectionPoint.java:92)
at org.jboss.weld.util.Beans.injectBoundFields(Beans.java:378)
at org.jboss.weld.util.Beans.injectFieldsAndInitializers(Beans.java:389)
at org.jboss.weld.injection.producer.ResourceInjector$1.proceed(ResourceInjector.java:70)
at org.jboss.weld.injection.InjectionContextImpl.run(InjectionContextImpl.java:48)
at org.jboss.weld.injection.producer.ResourceInjector.inject(ResourceInjector.java:72)
at org.jboss.weld.injection.producer.BasicInjectionTarget.inject(BasicInjectionTarget.java:121)
at org.hibernate.jpa.event.internal.jpa.ListenerFactoryBeanManagerStandardImpl$ListenerImpl.<init>(ListenerFactoryBeanManagerStandardImpl.java:93)
at org.hibernate.jpa.event.internal.jpa.ListenerFactoryBeanManagerStandardImpl$ListenerImpl.<init>(ListenerFactoryBeanManagerStandardImpl.java:82)
at org.hibernate.jpa.event.internal.jpa.ListenerFactoryBeanManagerStandardImpl.buildListener(ListenerFactoryBeanManagerStandardImpl.java:68)
at org.hibernate.jpa.event.internal.jpa.CallbackBuilderLegacyImpl.resolveCallbacks(CallbackBuilderLegacyImpl.java:170)
at org.hibernate.jpa.event.internal.jpa.CallbackBuilderLegacyImpl.buildCallbacksForEntity(CallbackBuilderLegacyImpl.java:69)
at org.hibernate.jpa.event.spi.JpaIntegrator.integrate(JpaIntegrator.java:134)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:276)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:465)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:881)
... 9 more
20:17:54,671 ERROR [org.jboss.as.controller.management-operation] (DeploymentScanner-threads - 2) WFLYCTL0013: Operation ("full-replace-deployment") failed - address: ([]) - failure description: {"WFLYCTL0080: Failed services" => {"jboss.persistenceunit.\"Test.ear/Test-ejb.jar#Test-ejbPU\"" => "org.jboss.msc.service.StartException in service jboss.persistenceunit.\"Test.ear/Test-ejb.jar#Test-ejbPU\": javax.persistence.PersistenceException: [PersistenceUnit: Test-ejbPU] Unable to build Hibernate SessionFactory
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: Test-ejbPU] Unable to build Hibernate SessionFactory
Caused by: org.jboss.weld.exceptions.IllegalArgumentException: WELD-001456: Argument resolvedBean must not be null"}}
根据this issue status,此问题已在Hibernate 5.1.0 final中修复。
其他:
当给出true
值时,应用程序成功,
<exclude-unlisted-classes>true</exclude-unlisted-classes>
和注释方法用于标记实体侦听器,避免orm.xml
中的XML映射,即Discount
实体用@EntityListeners(DiscountListener.class)
修饰时。
但是在我的环境中这样做是不允许的,因为我使用类库来桥接两个模块的共同功能,即EJB模块和我在类库中放置实体类的WAR模块(就我而言)有关,类库中的注入点不起作用,因为它没有Java EE环境 - 它不合格,因此,实体监听器和@EntityListeners(ListenerClass.class)
不能在其中使用。)
显然,如果采用这种方法,则需要将实体类添加到EJB模块和类库这两个地方,因为类库还需要在其编译时类中存在实体类-路径。这将导致java.lang.ClassCastException: com.example.Entity cannot be cast to com.example.Entity
,因为在运行时类路径上有重复的实体类。
►然而,这在GlassFish Server上取得了成功,并没有抱怨重复。
实体类和JPA静态元模型已放置在类库中,实体侦听器类已放置在关联的EJB模块中,并在/META-INF/orm.xml
(EJB模块)中注册。
整个问题中提到的方法在GlassFish Server / EclipseLink上成功。因此,我希望它适用于WildFly / Hibernate。
可能的方法是什么?它应该在不违反Java EE合同的情况下运行 - 不一定是我提到的唯一方法,但保持类库完整是必不可少的。
<子> P.S。据我所知,该项目不使用不支持类库的Apache Maven。