首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >未填充JPA/Hibernate静态元模型属性-- NullPointerException

未填充JPA/Hibernate静态元模型属性-- NullPointerException
EN

Stack Overflow用户
提问于 2010-10-04 19:12:43
回答 9查看 22K关注 0票数 25

我想对元模型对象使用JPA2 Criteria API,这看起来很简单:

代码语言:javascript
复制
...
Root<JPAAlbum> albm = cq.from(JPAAlbum.class);
... albm.get(JPAAlbum_.theme) ... ;

但是这个Root.get总是抛出一个NullPointerExceptionJPAAlbum_.theme是由Hibernate自动生成的,如下所示

代码语言:javascript
复制
public static volatile SingularAttribute<JPAAlbum, JPATheme> theme;

但很明显,它从来没有被填充过。

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

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

代码语言:javascript
复制
    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 )和相关的堆栈跟踪:

代码语言:javascript
复制
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)

EDIT 2:

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

在构建Hibernate EntityManagerFactory时,它将为已知的每个托管类型查找规范的元模型类,如果找到,它将向其中注入适当的元模型信息,如JPA2规范,第6.2.2节,第200页中所述

我也可以验证一下

代码语言:javascript
复制
     for (ManagedType o : em.getMetamodel().getManagedTypes()) {
            log.warn("___") ;
            for (Object p : o.getAttributes()) {
                log.warn(((Attribute)p).getName()) ;
            }
        }

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

代码语言:javascript
复制
   log.warn("_+_"+JPAPhoto_.id+"_+_") ;

仍然极度空虚..。

EDIT3:这是JPAAlbum entity及其metamodel class

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

  • I使用Hibernat 3.5.6-Final (根据META-INF/MANIFEST.MF),
  • 部署在Netbeans 6.9.1的Glassfish 3.0.1
  • 上;
  • 和应用程序依赖于EJB 3.1,

<代码>F229

我希望它能有所帮助!

EDIT 4:

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

代码语言:javascript
复制
java.lang.NullPointerException
    at org.hibernate.ejb.criteria.path.AbstractPathImpl.get(AbstractPathImpl.java:138)
    at net.wazari.dao.test.TestMetaModel.foo(TestMetaModel.java:55)

/.提供了一个简单得多的项目,它只包含我的实体和它们的元模型,外加一个测试(foo crashes metamodel,bar对于通常的查询是可以的。

EDIT 5:

您应该能够通过下载tarball、构建项目来重现该问题:

代码语言:javascript
复制
ant compile
or
ant dist

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

代码语言:javascript
复制
 CLASSPATH=`sh runTest.sh` java org.junit.runner.JUnitCore  net.wazari.dao.test.TestMetaModel

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

我使用的所有hibernate依赖项都应该包含在归档中。

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2011-02-04 05:43:57

我也遇到了同样的问题,通过将ModelModel_类放入同一个包中,修复了这个问题。

票数 52
EN

Stack Overflow用户

发布于 2011-11-10 22:32:44

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

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

它引用了JPA2规范,第6.2.1.1节,其中定义了应该如何构建静态元模型类。例如,通过阅读规范,我发现“此规范的未来版本中将提供不同包的选项”。我将元模型类放在不同的包中,它在EclipseLink上工作得很好,但它是一个额外的功能,正如当前标准所指出的:

  • 元模型类应与其描述的实体类位于同一包中;
  • 应与其描述的实体类具有相同的名称,后跟下划线(例如,

是实体,Product_是元模型类);

  • 如果实体继承自另一个实体或映射的超类,则其元模型类应从描述其直接超类的元模型类继承(例如,如果SpecialProduct扩展了产品,则SpecialProduct_应扩展Product_,后者应扩展Product

一旦我遵循了规范中的所有规则(上面只是一个总结,请参考规范的6.2.1.1节以获得完整版本),我就不再得到异常。

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

票数 12
EN

Stack Overflow用户

发布于 2010-11-07 23:06:02

我不能重现这个问题。我使用了您的一些实体( JPAAlbumJPAThemeJPATagTheme的简化版本,没有任何接口),生成了元模型类和下面的基本测试方法(在事务中运行):

代码语言:javascript
复制
@Test
public void foo() {
    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<JPAAlbum> query = builder.createQuery(JPAAlbum.class);

    Root<JPAAlbum> album = query.from(JPAAlbum.class);

    Assert.assertNotNull(album.get(JPAAlbum_.theme)); // no problem here

    query.where(builder.equal(album.get(JPAAlbum_.theme).get(JPATheme_.id), 1L));

    List<JPAAlbum> results = em.createQuery(query).getResultList();
}

FWIW,这是生成的SQL:

代码语言:javascript
复制
select
    jpaalbum0_.ID as ID32_,
    jpaalbum0_.AlbumDate as AlbumDate32_,
    jpaalbum0_.Description as Descript3_32_,
    jpaalbum0_.Nom as Nom32_,
    jpaalbum0_.Picture as Picture32_,
    jpaalbum0_.Theme as Theme32_ 
from
    Album jpaalbum0_ 
where
    jpaalbum0_.Theme=1

使用Hibernate EntityManager 3.5.6-Final,Hibernate JPAModelGen 1.1.0进行测试。最终,在任何容器之外。

我的建议是首先尝试在JUnit测试上下文中重现(如果可以重现)问题。

PS:顺便说一下,我不会在VCS中存储生成的类。

更新:是一个可以在测试上下文中使用的persistence.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
  version="2.0">
  <persistence-unit name="MyPu" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>

    <class>com.stackoverflow.q3854687.JPAAlbum</class>
    <class>com.stackoverflow.q3854687.JPATheme</class>
    <class>com.stackoverflow.q3854687.JPATagTheme</class>

    <exclude-unlisted-classes>true</exclude-unlisted-classes>

    <properties>
      <!-- Common properties -->
      <property name="javax.persistence.jdbc.driver" value="${jdbc.driver}" />
      <property name="javax.persistence.jdbc.url" value="${jdbc.url}" />
      <property name="javax.persistence.jdbc.user" value="${jdbc.user}" />
      <property name="javax.persistence.jdbc.password" value="${jdbc.password}" />

      <!-- Hibernate specific properties -->
      <property name="hibernate.dialect" value="${jdbc.dialect}" />
      <!--
      <property name="hibernate.show_sql" value="true"/>
      -->
      <property name="hibernate.format_sql" value="true" />
      <property name="hibernate.hbm2ddl.auto" value="update" />   
    </properties>
  </persistence-unit>
</persistence>
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3854687

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档