代码之家  ›  专栏  ›  技术社区  ›  Vinnie

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

  •  5
  • Vinnie  · 技术社区  · 16 年前

    我看到一条奇怪的错误信息,正在寻找一些关于问题可能是什么的想法。我对JPA还不太熟悉。

    我有一个应用程序,我使用spring的实体管理器工厂(localcontainerentitymanagerfactorybean),eclipseelink作为我的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的。

    如果你以前见过这个奇怪的问题,或者有什么想法可以纠正。

    2 回复  |  直到 16 年前
        1
  •  6
  •   Péter Török    16 年前

    这也可能是一个类加载问题。由两个不同的类加载器加载的同一个类定义被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 关于类加载的详细信息。

        2
  •  1
  •   Pascal Thivent    16 年前

    这闻起来很明显 ClassLoader 问题(可能是由于日食线需要编织)。你用 LoadTimeWeaver ?您是否配置了任何javaagent内容?问题是否出现在maven下的命令行上?在你的IDE里?请澄清。