写作时
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)
答案 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。