java JPA/Hibernate静态元模型属性未填充NullPointerException
我想将JPA2标准API用于元模型对象,这似乎非常简单:
...
Root<JPAAlbum> albm = cq.from(JPAAlbum.class);
... albm.get(JPAAlbum_.theme) ... ;
但是这个根。get总是抛出一个NullPointerException
JPAAlbum_.theme
由Hibernate自动生成,看起来像
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
)和关联的stacktrace:
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:
在JBossEntityManager指南中,我可以看到
When the Hibernate EntityManagerFactory is being built, it will look for a canonical metamodel class for each of the managed typed is knows about and if it finds any it will inject the appropriate metamodel information into them, as outlined in [JPA 2 Specification, section 6.2.2, pg 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 entity及其metamodel class
关于我的配置,我还能说些什么
我使用Hibernat3.5.6-Final(根据META-INF/MANIFEST.MF),
部署在Glassfish上3.0.1
来自Netbeans6.9.1
应用程序依赖于EJB3.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)
有一个简单得多的项目here/tarball它只包含我的实体和它们的元模型,加上一个JUnit测试(foo与元模型崩溃,bar与通常的查询无关)
编辑5:
您应该能够通过下载tarball生成项目来重现问题:
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
(编辑runTest.sh
将类路径指向JUnit4-5JAR的正确位置)
我使用的所有hibernate依赖项都应该包含在存档中
# 1 楼答案
我有一个JavaEE6应用程序,在GlassFish上使用EclipseLink,创建了一些@StaticMetamodel类,一切都很好。当我在JBoss7上切换到Hibernate 4时,我也开始使用这些NPE。我开始调查,发现了这个页面:
http://docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html/metamodel.html
它引用了JPA2规范第6.2.1.1节,该节定义了静态元模型类应该如何构建。例如,通过阅读规范,我发现“本规范的未来版本将提供不同包的选项”。我在不同的包中使用了元模型类,它在EclipseLink上运行良好,但这是一个额外的功能,正如当前的标准所示:
一旦我遵循了规范中的所有规则(以上只是一个总结,完整版本请参考规范第6.2.1.1节),我就不再得到例外
顺便说一下,您可以在这里下载规范:http://jcp.org/en/jsr/detail?id=317(点击“下载页面”查看最终版本,选择下载规范进行评估,接受协议并下载文件“SR-000317 2.0规范”-persistence-2_0-final-spec.pdf)
# 2 楼答案
类和元模型应该在同一个包中,即
文件夹实体:
我附上了一个元模型代码示例
# 3 楼答案
我也有同样的问题,通过将
Model
和Model_
类放在同一个包中解决了这个问题# 4 楼答案
仅供参考,我遇到了一个例子,Hibernate创建了一个元模型属性,但从未初始化它,在尝试使用它时会导致
NullPointerException
Hibernate在和类中生成
label
属性声明:。。。它将初始化
Upper_.label
,但使Lower_.label
等于null砰的一声
# 5 楼答案
如果将模型和模型放在同一个包中不起作用,我会提供另一种解决方案。您需要向构建SessionFactory或EntityManager的类添加一个init()方法:
因此,当您从main方法或单元测试运行应用程序时,需要首先调用
HibernateSessionFactory.init();
。然后NullPointerException神奇地消失,应用程序开始工作当通过方法参数传递
SingularAttribute
时,这种奇怪的行为似乎会发生归功于@CanÜNSAL,他在这个问题上解决了所有问题:Hibernate/JPA - NullPointerException when accessing SingularAttribute parameter
# 6 楼答案
我无法重现这个问题。我使用了您的一些实体(简化版的
JPAAlbum
、JPATheme
和JPATagTheme
,没有任何接口),生成了元模型类,以下基本测试方法(在事务内部运行)刚刚通过:FWIW,下面是生成的SQL:
使用Hibernate EntityManager 3.5.6-Final、Hibernate JPAModelGen 1.1.0进行测试。最后,在任何容器外
我的建议是,首先尝试在JUnit测试环境中重现(如果可以重现的话)这个问题
PS:顺便说一句,我不会在VCS中存储生成的类
更新:这里有一个
persistence.xml
可以在测试环境中使用: