升级至Hibernate 5.4.3后出现空指针异常,求技术支持
Hibernate 5.4.3升级后findUniqueWithNamedQuery方法空指针异常问题
原Web应用的HibernateCrudServiceDAO类在Hibernate 5.1.0版本下运行稳定,升级到5.4.3版本后出现问题:
- IntelliJ提示
org.hibernate.Query类和org.hibernate.query.Query.setFlushMode()方法过时,已替换为org.hibernate.query.Query类和setHibernateFlushMode()方法 - 替换后,
findUniqueWithNamedQuery方法抛出空指针异常
相关代码
HibernateCrudServiceDAO方法
@SuppressWarnings("unchecked") public <T> T findUniqueWithNamedQuery(String queryName, Map<String, Object> params){ Set<Entry<String, Object>> rawParameters = params.entrySet(); Query query = session.getNamedQuery(queryName); for(Entry<String, Object> entry : rawParameters){ query.setParameter(entry.getKey(), entry.getValue()); } return (T) query.setHibernateFlushMode(FlushMode.MANUAL).uniqueResult(); }
调用代码
User user = crudService.findUniqueWithNamedQuery(User.BY_CREDENTIALS, QueryParameters.with("userName", userName).and("password", digest).parameters());
命名查询
@NamedQuery(name = User.BY_CREDENTIALS, query = "Select u from User as u where u.userName = :userName and u.password = :password")
问题分析与解决方法
空指针的可能来源及对应处理:
Session或Named Query为空
session.getNamedQuery(queryName)可能返回null(比如命名查询不存在、Session未正确初始化)- 解决:增加非空校验,快速定位问题
Params参数为空
- 如果传入的
params为null,调用params.entrySet()会直接抛出空指针 - 解决:先判断params是否为空,再遍历参数
- 如果传入的
链式调用隐藏空指针
- 链式调用
query.setHibernateFlushMode(...).uniqueResult()如果query为空,会直接抛空指针,且难以定位是哪一步出问题 - 解决:拆分链式调用,分步执行
- 链式调用
修改后的代码:
@SuppressWarnings("unchecked") public <T> T findUniqueWithNamedQuery(String queryName, Map<String, Object> params){ // 校验Session有效性 if (session == null) { throw new IllegalStateException("Hibernate Session 未初始化"); } // 获取Named Query并校验 Query query = session.getNamedQuery(queryName); if (query == null) { throw new IllegalArgumentException("未找到指定命名查询: " + queryName); } // 处理参数(避免params为空时抛异常) if (params != null && !params.isEmpty()) { for (Map.Entry<String, Object> entry : params.entrySet()) { query.setParameter(entry.getKey(), entry.getValue()); } } // 拆分链式调用,避免空指针定位模糊 query.setHibernateFlushMode(FlushMode.MANUAL); return (T) query.uniqueResult(); }
额外注意:确保代码中导入的Query是org.hibernate.query.Query,不要残留旧的org.hibernate.Query导入,避免类混淆。
内容的提问来源于stack exchange,提问作者Christopher Dodunski
相关产品推荐
相关产品推荐

