我看到一个奇怪的错误消息,并且正在寻找一些有关问题可能出在哪里的想法。我是使用JPA的新手。
我有一个应用程序,在其中使用Spring的实体管理器工厂(LocalContainerEntityManagerFactoryBean),EclipseLink作为我的ORM提供程序,并连接到MySQL数据库并由Maven构建。我不确定这是否重要.....
当我将此应用程序部署到Glassfish时,该应用程序将按预期工作。
问题是,我创建了一组独立的单元测试,以在无法正常运行的Glassfish之外运行。我收到以下错误( 我已经稍微编辑了类名 )
com.xyz.abc.services.persistence.entity.MyEntity cannot be cast to com.xyz.abc.services.persistence.entity.MyEntity
对象不能转换为相同类型的类吗?怎么可能?
这是错误的代码片段
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中使用的某个罐子与我在测试中使用的罐子不同。我已经查看了所有列为“提供”的罐子,并且可以肯定它们与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当然,可以使用对首选日志记录框架的调用来代替。
System.out.println
这是一系列有关类加载的详细信息。