我看到一个奇怪的错误消息,我正在寻找一些关于问题可能是什么的想法。我对使用JPA有点新意。
我有一个应用程序,我使用Spring的Entity Manager Factory(LocalContainerEntityManagerFactoryBean),EclipseLink作为我的ORM提供程序,连接到MySQL DB并使用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的罐子。
如果您之前看到过这个奇怪的问题,或者有任何纠正错误的想法,请告诉我。
答案 0 :(得分:6)
这也可能是类加载问题。由两个不同的类加载器加载的相同类定义被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
。
以下是a series of articles,其中包含有关类加载的更多详细信息。
答案 1 :(得分:1)
这显然会引发ClassLoader
问题(可能是由于EclipseLink需要编织)。你使用LoadTimeWeaver
吗?你有配置javaagent的东西吗?是否在Maven下的命令行中出现问题?在你的IDE?请澄清。