JPA/Hibernate Static Metamodel Attributes 未填充 -- NullPointerException

我想将JPA2 Criteria API与元模型对象一起使用,这似乎很容易:

...
Root<JPAAlbum> albm = cq.from(JPAAlbum.class);
... albm.get(JPAAlbum_.theme) ... ;

但是这个 Root.get 总是抛出一个 . 由Hibernate自动生成,看起来像NullPointerExceptionJPAAlbum_.theme

public static volatile SingularAttribute<JPAAlbum, JPATheme> theme;

但它显然从未被填充过。

我是否在框架初始化中遗漏了一个步骤?

编辑:这是我在崩溃时使用JPA和元模型的片段:

    CriteriaBuilder cb = em.getCriteriaBuilder();

    CriteriaQuery<JPAAlbum> cq = cb.createQuery(JPAAlbum.class) ;
    Root<JPAAlbum> albm = cq.from(JPAAlbum.class);
    cq.where(cb.equal(albm.get(JPAAlbum_.theme).get(JPATheme_.id),
                        session.getTheme().getId())) ;

(JPAAlbum_是一个类,所以我就在前面)和关联的堆栈跟踪:import

Caused by: java.lang.NullPointerException
    at org.hibernate.ejb.criteria.path.AbstractPathImpl.get(AbstractPathImpl.java:138)
    at net.wazari.dao.jpa.WebAlbumsDAOBean.getRestrictionToAlbumsAllowed(WebAlbumsDAOBean.java:55)

编辑2:

在 JBoss EntityManager 指南中,我可以看到

当Hibernate EntityManagerFactory正在构建时,它将为每个托管类型化已知的元模型类寻找一个规范元模型类,如果找到任何,它将向其中注入适当的元模型信息,如[JPA 2规范,第6.2.2节,第200页]中所述。

我也可以验证

     for (ManagedType o : em.getMetamodel().getManagedTypes()) {
            log.warn("___") ;
            for (Object p : o.getAttributes()) {
                log.warn(((Attribute)p).getName()) ;
            }
        }

Hibernate知道我的元模型,但是属性名称是写的

   log.warn("_+_"+JPAPhoto_.id+"_+_") ;

仍然空虚无垠...

EDIT3:这是JPAAlbum实体及其元模型类

关于我的配置,我还能说些什么...

  • 我使用Hibernat 3.5.6-Final(根据META-INF / MANIFEST。MF),

  • 部署在 Glassfish 3.0.1 上

  • 来自 Netbeans 6.9.1;

  • 并且应用程序依赖于 EJB 3.1

我希望它会有所帮助!

编辑4:

不幸的是,JUnit测试导致了同样的异常:

java.lang.NullPointerException
    at org.hibernate.ejb.criteria.path.AbstractPathImpl.get(AbstractPathImpl.java:138)
    at net.wazari.dao.test.TestMetaModel.foo(TestMetaModel.java:55)

一个更简单的项目可以在这里/压缩包它只包含我的实体和它们的元模型,加上一个JUnit测试(foo与元模型崩溃,bar与通常的查询是可以的。

编辑5:

您应该能够通过下载压缩包并构建项目来重现问题:

ant compile
or
ant dist

并启动 JUnit 测试net.wazari.dao.test.TestMetaModel

 CLASSPATH=`sh runTest.sh` java org.junit.runner.JUnitCore  net.wazari.dao.test.TestMetaModel

(编辑以将CLASSPATH指向JUnit4-5罐的正确位置)runTest.sh

我使用的所有休眠依赖项都应包含在存档中。


答案 1

我遇到了同样的问题,通过将和类放入同一包中来修复它。ModelModel_


答案 2

我有一个Java EE 6应用程序,在GlassFish上使用EclipseLink,并创建了一些@StaticMetamodel类,一切正常。当我在JBoss 7上切换到Hibernate 4时,我也开始获得这些NPE。我开始调查,我发现这个页面:

http://docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html/metamodel.html

它引用了 JPA 2 规范,第 6.2.1.1 节,它定义了应该如何构建静态元模型类。例如,我通过阅读规范发现“此规范的未来版本中将提供不同软件包的选项”。我在不同的包中拥有元模型类,它在EclipseLink上工作正常,但这是一个额外的功能,因为当前的标准表明了以下几点:

  • 元模型类应与它们描述的实体类位于同一包中;
  • 它们应该与它们描述的实体类具有相同的名称,后跟下划线(例如,Product是实体,Product_是元模型类);
  • 如果一个实体从另一个实体或映射的超类继承,则其元模型类应继承描述其直接超类的元模型类(例如,如果 SpecialProduct 扩展了 Product,它扩展了 PersistentObject,那么SpecialProduct_应该扩展Product_它应该扩展PersistentObject_)。

一旦我遵循了规范中的所有规则(以上只是一个摘要,请参阅完整版本的规范的6.2.1.1节),我就停止了异常。

顺便说一句,您可以在此处下载规范:http://jcp.org/en/jsr/detail?id=317(单击“下载页面”以获取最终版本,选择下载规范进行评估,接受协议并下载文件“SR-000317 2.0规范” - persistence-2_0-final-spec.pdf)。


推荐