Hibernate / JPA - 访问SingularAttribute参数时出现NullPointerException [英] Hibernate/JPA - NullPointerException when accessing SingularAttribute parameter

查看:1091
本文介绍了Hibernate / JPA - 访问SingularAttribute参数时出现NullPointerException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Hibernate 5.0.7.Final的JPA2类型安全条件查询。

I'm trying to use JPA2 type-safe criteria queries with Hibernate 5.0.7.Final.

...
criteria.where( builder.equal( root.get(SingularAttribute.attr), value ));
//where parameters are
//criteria.where( builder.equal( root.get(Person_.name), "Can" ));
...

root.get总是抛出 NullPointerException
org.hibernate.jpamodelgen生成的元模型类 Person _ .JPAMetaModelEntityProcessor

The root.get always throw NullPointerException. The metamodel class Person_ for Person is generated by org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor.

JPA / Hibernate静态元模型属性未填充 - NullPointerException 但这次两个类都在同一个包中。

A similar problem was asked in JPA/Hibernate Static Metamodel Attributes not Populated -- NullPointerException but this time both classes are in the same package.

堆栈跟踪:

java.lang.NullPointerException
at org.hibernate.jpa.criteria.path.AbstractPathImpl.get(AbstractPathImpl.java:123)

我的代码:

用于确保它们具有 getId(); 的接口。

Interface that i use to make sure they will have getId();.

package it.unibz.db.hibernate.model;

public interface ModelInterface<PK extends Serializable> extends Serializable {
    PK getId();
}

模型类

package it.unibz.db.hibernate.model;

@Entity
@Table(name ="person")
public class Person implements ModelInterface<Integer> {
    @Id
    private Integer id;
    private String name;

    public Integer getId() {
        return id;
    }
    //other getter and setters
}

生成metamodel Person_ class

Generated metamodel Person_ class

package it.unibz.db.hibernate.model;

@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
@StaticMetamodel(Person.class)
public abstract class Person_ {

    public static volatile SingularAttribute<Person, String> name;
    public static volatile SingularAttribute<Person, Integer> id;

}

我用PersonDao继承的通用DAO类

Generic DAO class that i inherit with PersonDao

public class GenericDao<E extends ModelInterface<PK>, PK extends Serializable> implements DaoInterface<E, PK> {
private Class<E> type;

public GenericDao(Class<E> type) {
    this.type = type;
    //called as super(ClassName.class); eg. super(Person.class);
}

public List<E> readBy(SingularAttribute column, String value) throws Exception {
    EntityManager em = HibernateUtil.getEntityManager();
    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<E> criteria = builder.createQuery(type);
    Root<E> root = criteria.from(type);

    criteria.select(root);
    criteria.where( builder.equal( root.get(column), value ));
    List<E> entityList = em.createQuery(criteria).getResultList();
    em.close();
    return entityList;
    }
}

我的一些依赖项


  • hibernate-c3p0 5.0.7.Final

  • hibernate-c3p0 5.0.7.Final

hibernate-entitymanager 5.0.7 .Final

hibernate-entitymanager 5.0.7.Final

postgresql 9.4.1207.jre7

postgresql 9.4.1207.jre7

hibernate-jpamodelgen 5.0.7 .Final

hibernate-jpamodelgen 5.0.7.Final

编辑:

在main方法中运行此代码

Running this code in the main method works

EntityManager em = HibernateUtil.getEntityManager();
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Person> criteria = builder.createQuery(Person.class);
Root<Person> root = criteria.from(Person.class);
criteria.select(root);
criteria.where( builder.equal( root.get(Person_.name), "Can" ));
List<Person> entityList = em.createQuery(criteria).getResultList();
//do stuff with entityList

,但方法中包含的相同代码会抛出 NullPointerException

but the same code covered in a method throws NullPointerException.

public List<Person> readBy(SingularAttribute column, String value) throws Exception {
    log.debug("Reading entity by");

    EntityManager em = HibernateUtil.getEntityManager();
    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<Person> criteria = builder.createQuery(Person.class);
    Root<Person> root = criteria.from(Person.class);

    criteria.select(root);
    criteria.where( builder.equal( root.get(column), value ));
    List<Person> entityList = em.createQuery(criteria).getResultList();
    em.close();
    return entityList;
}

所以似乎问题是传递 SingularAttribute 方法的参数 readBy(SingularAttribute列,字符串值)

So it seems that the problem is passing SingularAttribute parameter to the method readBy(SingularAttribute column, String value).

我测试了这个main中的代码打印 false

I tested this code in main and this prints false

EntityManager em = HibernateUtil.getEntityManager();
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Person> criteria = builder.createQuery(Person.class);
Root<Person> root = criteria.from(Person.class);
System.out.println(root.get(Person_.name) == null); //false

同时抛出 InvocationTargetException 导致by NullPointerException at root.get(column)

meanwhile this throws InvocationTargetException caused by NullPointerException at root.get(column).

//invoked as personDao.test(Person_.name) from main
public void test(SingularAttribute column) {
    EntityManager em = HibernateUtil.getEntityManager();
    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<Person> criteria = builder.createQuery(Person.class);
    Root<Person> root = criteria.from(Person.class);
    System.out.println(root.get(column) == null); //InvocationTargetException
}

这是它应该做的吗?如何将 SingularAttribute 对象作为参数传递给方法?

Is this what it's supposed to do? How can i pass SingularAttribute object to a method as a parameter?

推荐答案

在方法调用以某种方式工作之前,在main中调用 HibernateUtil.getEntityManager()它甚至可以在我称之为方法的空块 init()
它可能与类的初始化有关。这是代码片段。

Calling HibernateUtil.getEntityManager() in main before method call somehow works. It even works when i call literally a empty block of a method init(). It could be related with initialization of classes. Here's the code snippet.

public class HibernateUtil {
    private static EntityManagerFactory emFactory;
    private static EntityManager em;
    private static final Logger log = LoggerFactory.getLogger(HibernateUtil.class);
    private static final String PERSISTENCE_UNIT = "pt";
    static{
        log.info("Creating entity manager factory");
        emFactory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT);
    }
    //calling this from main before PersonDao's method calls somehow works...
    public void init(){} //does nothing
    public static EntityManager getEntityManager(){
        if(em != null && em.isOpen()){
            closeEntityManager();
        }
        log.debug("Creating new entity manager");
        em = emFactory.createEntityManager();
        return em;
    }
    public static void close() throws Exception {
        if(em != null && em.isOpen()){
            closeEntityManager();
        }
        log.info("Closing entity manager factory");
        emFactory.close();
    }
    private static void closeEntityManager(){
        log.info("Closing last entity manager");
        em.close();
    }
}

这篇关于Hibernate / JPA - 访问SingularAttribute参数时出现NullPointerException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆