Java 服务器部署的持久化单元存在类加载问题
我在一个EAR包中遇到了一个问题,该包在EJBMDule中包含一个服务器部署的持久化单元,在WAR模块中包含一个web应用程序Java 服务器部署的持久化单元存在类加载问题,java,classloader,wildfly,Java,Classloader,Wildfly,我在一个EAR包中遇到了一个问题,该包在EJBMDule中包含一个服务器部署的持久化单元,在WAR模块中包含一个web应用程序 EAR |--- persistence unit (EJB module) |--- web app (WAR) ... 一切都已编译,部署(在WildFly 10 CR5下)已成功执行。正确部署持久性单元并创建模式(在开发期间使用Hibernate模式生成) 但是,当我试图持久化其中一个实体时 MyEntitiy e = new MyEntitiy();
EAR
|--- persistence unit (EJB module)
|--- web app (WAR)
...
一切都已编译,部署(在WildFly 10 CR5下)已成功执行。正确部署持久性单元并创建模式(在开发期间使用Hibernate模式生成)
但是,当我试图持久化其中一个实体时
MyEntitiy e = new MyEntitiy();
e.setId(UUID.randomUUID().toString());
e.setName("name");
entityService.save(e);
我得到一个运行时错误,其根本原因是:
Caused by: java.lang.IllegalArgumentException: Can not set java.lang.String field x.y.z.MyEntity.id to x.y.z.MyEntity
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36)
at java.lang.reflect.Field.get(Field.java:393)
at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:39)
潜入调试器,我找到了方法sun.reflect.UnsafeFieldAccessorImpl.ensureObj
,它通过方法Class.isAssignableFrom
在类之间执行检查
字段
对象的类(字段.getDeclaredClass()
)ClassLoader
s加载(它们在逻辑上是相同的类)
如何在不改变项目的一般布局的情况下克服这个问题(即,将持久性单元保持为EJB模块,以便在各个模块之间共享)?我相信,您可能已经在EJBJAR和war文件中包含了MyEntity类(或实体),因此它们将由两个类加载器加载。您可能需要从war文件中删除域实体并对其进行测试
根据jboss文档,默认情况下,ejb jar中定义的类可用于war文件中的类。因此,它们将仅由ejb类加载器加载一次,并且也将用于war文件中的类。您是否同时在ejb jar和war文件中打包MyEntity类(或实体)?@Madhusudanareddysunapu Yesalt尽管我还没有根据jboss文档对其进行测试,您可能希望从war文件和测试中删除域实体。根据文档,ejb jar中定义的类在默认情况下可用于war文件中的类。@MadhusudanaReddySunnapu hi!我花了一段时间才能彻底测试您的解决方案(为此我必须重写部分核心代码)。如果你想给这个问题一个答案,我很乐意接受。很高兴这有帮助。我把它作为一个答案发布,这样其他人也可以从中受益。