Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 头脑风暴:奇怪的JPA问题,可能是类路径或jar版本控制问题?_Java_Spring_Jpa_Classloader_Eclipselink - Fatal编程技术网

Java 头脑风暴:奇怪的JPA问题,可能是类路径或jar版本控制问题?

Java 头脑风暴:奇怪的JPA问题,可能是类路径或jar版本控制问题?,java,spring,jpa,classloader,eclipselink,Java,Spring,Jpa,Classloader,Eclipselink,我看到一条奇怪的错误信息,我想知道问题可能是什么。我对使用JPA有点陌生 我有一个应用程序,其中我使用Spring的实体管理器工厂(LocalContainerEntityManagerFactoryBean),EclipseLink作为我的ORM提供程序,连接到MySQL数据库并使用Maven构建。我不确定这些是否重要 当我将此应用程序部署到Glassfish时,该应用程序按预期工作 问题是,我已经创建了一组独立的单元测试,在Glassfish之外运行,这些测试无法正常工作。我得到以下错误(我

我看到一条奇怪的错误信息,我想知道问题可能是什么。我对使用JPA有点陌生

我有一个应用程序,其中我使用Spring的实体管理器工厂(LocalContainerEntityManagerFactoryBean),EclipseLink作为我的ORM提供程序,连接到MySQL数据库并使用Maven构建。我不确定这些是否重要

当我将此应用程序部署到Glassfish时,该应用程序按预期工作

问题是,我已经创建了一组独立的单元测试,在Glassfish之外运行,这些测试无法正常工作。我得到以下错误(我编辑了一些类名)

对象不能强制转换为相同类型的类?这怎么可能

下面是一段出错的代码

Query q = entityManager.createNamedQuery("MyEntity.findAll");
List entityObjects = q.getResultList();
for (Object entityObject: entityObjects) {
   com.xyz.abc.services.persistence.entity.MyEntity entity = (com.xyz.abc.services.persistence.entity.MyEntity) entityObject;
以前,我有一段代码产生了相同的错误:

CriteriaQuery cq = entityManager.getCriteriaBuilder().createQuery();
cq.select(cq.from(com.xyz.abc.services.persistence.entity.MyEntity.class));
List entityObjects = entityManager.createQuery(cq).getResultList();
for (Object entityObject: entityObjects) {
   com.xyz.abc.services.persistence.entity.MyEntity entity = (com.xyz.abc.services.persistence.entity.MyEntity) entityObject;
此代码与我部署到服务器的代码相同

如果有帮助的话,这里是最内部的例外

Caused by: java.lang.ClassCastException: com.xyz.abc.services.persistence.entity.MyEntity cannot be cast to com.xyz.abc.services.persistence.entity.MyEntity
    at com.xyz.abc.services.persistence.entity.factory.MyEntityFactory.createBeans(MyEntityFactory.java:47)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:115)
    ... 37 more
我猜我在玻璃鱼中使用的罐子和我在测试中使用的不同。我已经看过了我列出的所有“提供”的罐子,我很确定它们都是来自Glassfish的


如果您以前看到过这个奇怪的问题,请告诉我,或者有什么想法可以纠正它。

这也可能是类加载问题。由两个不同的类加载器加载的同一个类定义被JVM视为不同的类

您可以尝试此操作以获取有关游戏中类装入器的信息:

Query q = entityManager.createNamedQuery("MyEntity.findAll");
List entityObjects = q.getResultList();

ClassLoader loader1 = 
    com.xyz.abc.services.persistence.entity.MyEntity.getClass().getClassLoader();
System.out.println("MyEntity's class loader is " + loader1);
for (Object entityObject: entityObjects) {
  ClassLoader loader2 = entityObject.getClass().getClassLoader();
  System.out.println("Class loader of entity " + entityObject + " is " + loader2);
}
当然,您可以使用对首选日志框架的调用,而不是
System.out.println


下面是关于类加载的更多细节。

这显然是一个
类加载程序的问题(可能是由于EclipseLink需要编织)。您是否使用
LoadTimeWeaver
?您配置了javaagent吗?问题是否发生在Maven下的命令行上?在你的IDE中?请澄清。

关于编织的观点很好,我想在问题中提到这一点。我在Glassfish中使用org.springframework.context.weave.DefaultContextLoadTimeWeaver,在测试中使用org.springframework.instrument.classloading.SimpleLoadTimeWeaver。我不确定该使用哪个,所以我只选择了一个似乎有效的。顺便说一句,我没有配置任何javaagent。问题出现在maven命令行和IDE中。Glassfish服务器是我唯一没有发现问题的地方。是的,好的,这似乎是个问题。以下是输出:MyEntity的类加载器是sun.misc.Launcher$AppClassLoader@1ea2dfeMyEntity对象的类装入器是org.springframework.instrument.classloading。SimpleInstrumentableClassLoader@16089a5现在如何修复它???我将深入研究你链接到的那些文章。@Vinnie不幸的是,我不熟悉你使用的工具,所以我无法提供更具体的帮助。祝你好运——你需要它……好吧,这可能是一个新手的错误,但是你的建议(以及关于在本地使用不同类加载器的启示)导致了一个可行的解决方案。看到有不同的类加载器在起作用,我认为Spring的LocalContainerEntityManagerFactoryBean不是在单元测试中使用的正确选择。我切换到LocalEntityManagerFactoryBean(这也意味着我需要一个新的持久化单元,因为我无法注入数据源),现在事情似乎在本地运行。谢谢你的帮助!
Query q = entityManager.createNamedQuery("MyEntity.findAll");
List entityObjects = q.getResultList();

ClassLoader loader1 = 
    com.xyz.abc.services.persistence.entity.MyEntity.getClass().getClassLoader();
System.out.println("MyEntity's class loader is " + loader1);
for (Object entityObject: entityObjects) {
  ClassLoader loader2 = entityObject.getClass().getClassLoader();
  System.out.println("Class loader of entity " + entityObject + " is " + loader2);
}