使用JDO持久化/检索Object时,DataNucleus DAO对象中的ClassCastException

时间:2010-10-25 14:11:35

标签: java classloader jdo db4o datanucleus

我使用Spring& amp;创建了一个简单的webapp。 Jetty,我正在使用DataNucleus&创建一个hello world JDO测试。 DB4O。

我可以坚持上课没有问题,但是当我去查询课程时我得到ClassCastException,无法将a.b.c.MyClass强制转换为a.b.c.MyClass

当我检查我创建的原始对象的类加载器时,它是[WebAppClassLoader@1592226291],当然它是弹簧WebApp类加载器。

我在同一个servlet方法中执行persist操作和查询操作,当我通过简单查询从DB重新读取对象时,我从DB中获取一组abcMyClass对象,但是类加载器是[sun.misc.Launcher$AppClassLoader@5acac268],因此例外。

在此处跟踪DataNucleus文档http://www.datanucleus.org/extensions/classloader_resolver.html

  

...... JDO2类加载机制   使用3级装载机
  *在创建PersistenceManagerFactory时可以   指定一个类加载器。这是用的   首先,如果指定
  *要尝试的第二个类加载器是当前的类加载器   线程。
  *要尝试的第三个类加载器是PMF上下文的类加载器。

我介绍了记录的前两个选项,并验证了类加载器是Servlet中的WebAppClassLoader,其中包含servlet中的这些调试步骤:

Thread.currentThread().getContextClassLoader().toString()
((JDOPersistenceManagerFactory)pm.getPersistenceManagerFactory()).getPrimaryClassLoader().toString()

两者都将[WebAppClassLoader@1592226291]作为类加载器。

我不确定我在哪里出错了。

1 个答案:

答案 0 :(得分:1)

我之前的评论作为答案:

此异常表明它是类加载器问题。比较对象的类加载器和您用于转换的类。

ClassLoader loaderOfObject = theObject.getClass().getClassLoader();
ClassLoader loaderOfLocalClass = MyClass.getClassLoader();
// have to be the same.
assert loaderOfObject.equals(loaderOfLocalClass);

顺便说一句:如果db4o使用了错误的类加载器。您可以通过配置class-loader explicit来更改它。

    EmbeddedConfiguration configuration = Db4oEmbedded.newConfiguration();
    JdkReflector reflector = new JdkReflector(Thread.currentThread().getContextClassLoader());
    configuration.common().reflectWith(reflector);
    ObjectContainer container = Db4oEmbedded.openFile(configuration, "database.db4o");

当单个类加载器不够时:您还可以传递db4o-interface JdkLoader的实例而不是类加载器。在那里,您可以实现任何类查找方法。例如,查找多个类加载器。