Hibernate查询实体返回空、未自动加载关联映射对象/列表如何解决?
修复方案
首先要先明确当前异常的直接触发原因:你抛出的NullPointerException首先是entityManager.find(Employee.class, 1L)返回了null导致的,也就是数据库中不存在主键为1的Employee记录,你可以先校验数据库中对应主键的记录是否真实存在。
如果确认记录存在,且实际遇到的是关联对象personalDetail为null的懒加载未生效问题,可通过以下几种方式修复:
- 方案1:显式指定关联属性的立即抓取策略
@OneToOne默认的抓取策略是FetchType.EAGER,如果你的配置被修改为懒加载,可直接在注解上显式声明立即加载:
@OneToOne(fetch = FetchType.EAGER) @JoinColumn(name = "personal_detail_id") private PersonalDetail personalDetail;
注意:如果personal_detail_id字段本身为null,或者关联的PersonalDetail表中对应记录不存在,就算用立即加载也会返回null,需要先校验关联数据的完整性
- 方案2:查询时通过fetch join主动加载关联对象
如果不想修改全局的抓取策略,可以用JPQL的fetch join语法,在查询Employee时同时拉取关联的personalDetail数据:
Employee employee = entityManager.createQuery( "SELECT e FROM Employee e LEFT JOIN FETCH e.personalDetail WHERE e.id = :id", Employee.class ) .setParameter("id", 1L) .getSingleResult();
这种方式对原有代码侵入性低,仅在当前需要关联数据的查询场景下生效,不会影响其他业务的查询性能。
方案3:保证访问关联属性时持久化上下文处于开启状态
如果你要用懒加载策略,必须保证调用getPersonalDetail()方法时,对应的entityManager还没有关闭。如果是Spring项目,给业务方法加上@Transactional注解即可让方法执行全程保持持久化上下文开启,访问关联属性时会自动触发二次查询加载数据。额外空值防护
不管采用哪种加载方案,都建议增加空值判断避免不必要的空指针异常:
employee = entityManager.find(Employee.class, 1L); if (employee != null && employee.getPersonalDetail() != null) { Assert.assertEquals(employee.getPersonalDetail().getBirthPlace(), "New Jersey"); } else { Assert.fail("员工数据或对应的个人详情数据不存在"); }
内容的提问来源于stack exchange,提问作者JONKI
相关产品推荐
相关产品推荐

