Hibernate DetachedCriteria嵌套子查询触发空指针,求实现方案
解决Hibernate DetachedCriteria嵌套子查询空指针异常的方案
嘿,我完全懂你现在的困扰——用Hibernate的DetachedCriteria做嵌套子查询时碰上空指针,还找不到Subqueries.exists()的靠谱示例,查了半天也没解决对吧?别慌,我来给你拆解问题,一步步搞定它。
1. 先明确示例场景(方便理解代码)
假设我们有两个关联的实体类:
Order:订单实体,包含id、orderNumber等字段,一个订单对应多个订单项OrderItem:订单项实体,包含id、productName,以及关联的Order对象(字段名order)
我们的需求是:查询存在有效订单项的所有订单,这时候就需要用到Subqueries.exists()来实现嵌套子查询。
2. 正确的Subqueries.exists()使用示例
下面是完整的可运行代码示例,按照这个写法基本能避免空指针:
// 1. 构建主查询:查询Order实体 DetachedCriteria mainQuery = DetachedCriteria.forClass(Order.class); // 2. 构建子查询:判断是否存在对应的OrderItem DetachedCriteria subQuery = DetachedCriteria.forClass(OrderItem.class); // 关联主查询和子查询的字段:子查询中OrderItem的order.id 等于主查询中Order的id subQuery.add(Restrictions.eqProperty("order.id", "this.id")); // 关键!exists子查询必须设置投影(随便选一个非空字段即可,比如id) subQuery.setProjection(Projections.property("id")); // 3. 将子查询作为exists条件添加到主查询 mainQuery.add(Subqueries.exists(subQuery)); // 4. 执行查询(确保session是有效的Hibernate Session) List<Order> validOrders = mainQuery.getExecutableCriteria(session).list();
3. 空指针异常的常见原因及排查
你碰到的空指针,大概率是以下几个原因之一:
- 子查询未正确初始化:检查
DetachedCriteria.forClass()传入的实体类是否正确,有没有拼写错误,实体类是否已经被Hibernate正确映射(比如加了@Entity注解)。 - 关联字段拼写错误:比如把
eqProperty("order.id", "this.id")写成了eqProperty("orderId", "id"),Hibernate找不到对应属性就会引发空指针,一定要严格对应实体类的字段名。 - 忘记设置投影:这是最容易踩的坑!
Subqueries.exists()要求子查询必须有投影(因为exists只需要判断是否有结果,不需要返回完整实体),如果没加setProjection(),十有八九会触发空指针。 - Session为null:执行
getExecutableCriteria(session)时,如果session是null,直接就会抛出空指针,要确保session是有效的(比如Spring环境中通过@Autowired获取,或者手动打开session)。
4. 调试小技巧
如果还是找不到问题根源,可以试试这些方法:
- 在关键位置加日志,比如打印
subQuery和session是否为null。 - 开启Hibernate的SQL日志,查看生成的SQL语句是否符合预期,有没有语法错误。
- 用debug模式一步步走,看哪个对象在调用方法时变成了null。
内容的提问来源于stack exchange,提问作者David Bezerra
相关产品推荐
相关产品推荐

