冬眠中的魔法npe

时间:2013-08-09 14:50:37

标签: java hibernate hql

写作时

Session session = sessionFactory.getCurrentSession();
List<Candidate> candidates = (List<Candidate>) session.createQuery(
        "select Candidate from Candidate as candidate  left outer join"
        + " candidate.skills as skill    where skill.id =" + 1).list();

我在第二行npe

如果我写

Session session = sessionFactory.getCurrentSession();
List<Candidate> candidates = (List<Candidate>) session.createSQLQuery(
        "select candidate.* from candidate inner join candidate_skill"
        + " on candidate.id = candidate_skill.candidate_id"
        + " inner join skill on candidate_skill.skill_id = skill.id"
        + " where skill.id = 1").list();

我的结果很好

为什么我在第一个例子中有NPE?

  

SEVERE:Servlet [appServlet]的Servlet.service()在路径[/ ui]的上下文中引发异常[请求处理失败;具有根本原因的嵌套异常是java.lang.NullPointerException]       显示java.lang.NullPointerException           在org.hibernate.dialect.function.SQLFunctionRegistry.findSQLFunction(SQLFunctionRegistry.java:41)

enter image description here

1 个答案:

答案 0 :(得分:9)

从第一个查询中删除select Candidate(您是否在Candidate实体中有字段Candidate? 完整实体选择的HQL语法为from <mapped entity>...


关于您的问题:

魔法NPE如何发生:(...经过一些调试或HQL解析器后)
HQL解析器 - 在AST构建期间 - 查找名为Candidate的属性引用,但找不到它,所以尝试解析为ClassName或函数(查看org.hibernate.hql.internal.ast.util.LiteralProcessor.processConstant()函数);候选者是一个类名和解析器威胁它作为一个鉴别器值(用于实体子类)返回null 在该解析器之后,在select的显式列表的翻译期间找到值为Candidate的{​​{1}}并尝试解析为函数,因为null不是有效的dataType(实体,原语或其他有效的数据类型)所以尽量把它们解决为一个功能;值null我们用作函数null的参数,作为此正文:

SQLFunctionRegistry.findSQLFunction()

public SQLFunction findSQLFunction(String functionName) { return sfi.getSqlFunctionRegistry().findSQLFunction( functionName.toLowerCase() ); } 会导致NPE。