Hibernate left join fetch查询仅返回date_to为null的Assignment避免额外查询咨询
问题根因
你之前的JPQL仅执行了普通左关联,没有使用FETCH关键字指定加载关联的assignment集合,因此返回的Role对象中assignment属性仍然是未初始化的懒加载代理。当你调用getAssignments()时,Hibernate会触发全量关联查询加载该Role的所有Assignment,不会携带dateTo is null的过滤条件。
解决方案
方案1:使用带过滤条件的LEFT JOIN FETCH(推荐,单次查询实现)
JPA 2.1及以上版本支持在JOIN FETCH后追加ON子句自定义过滤条件,直接一次性加载符合要求的关联数据:
@Query("SELECT DISTINCT r FROM Role r " + "LEFT JOIN FETCH r.assignment av ON av.dateTo IS NULL " + "LEFT JOIN FETCH av.permissions p " + "WHERE r.name IN :names") @QueryHints(@QueryHint(name = org.hibernate.jpa.QueryHints.HINT_PASS_DISTINCT_THROUGH, value = "false")) List<Role> readByRoleNameInOnlyActiveAssignments(List<String> names);
说明:
FETCH关键字会告知Hibernate直接初始化关联的assignment和permissions集合,后续调用getAssignments()不会触发额外查询LEFT JOIN FETCH保证没有符合条件Assignment的Role也会被保留,不会被过滤DISTINCT用于合并SQL层面关联查询产生的重复Role实体,HINT_PASS_DISTINCT_THROUGH=false会禁止将DISTINCT传递到SQL语句,避免不必要的性能损耗- 返回的Role对象中
assignment集合已自动过滤仅保留dateTo为null的记录,无符合条件数据时为空集合
方案2:使用Hibernate @Filter 注解(适合多场景复用过滤规则)
如果需要在多个查询场景下都只返回生效的Assignment,可以给关联集合配置全局过滤器:
- 给Role的assignment集合增加过滤器配置:
@OneToMany(mappedBy = "role") @Filter(name = "activeAssignment", condition = "date_to is null") private List<Assignment> assignment;
- 查询前手动开启过滤器:
entityManager.unwrap(Session.class) .enableFilter("activeAssignment") .validate(); // 后续执行任意Role查询,懒加载assignment时都会自动携带date_to is null的条件 List<Role> roles = roleRepository.readByRoleNameIn(names);
方案3:DTO投影(适合只读查询场景)
如果返回结果仅用于展示不需要修改,可自定义DTO封装需要的字段,完全规避实体懒加载问题:
// 定义DTO类 public class RoleWithActiveAssignmentsDTO { private Long roleDbid; private String roleName; private List<Assignment> activeAssignments; // 全参数构造方法、getter方法 } // 编写JPQL查询 @Query("SELECT new com.xxx.dto.RoleWithActiveAssignmentsDTO(r.dbid, r.name, collect(av)) " + "FROM Role r LEFT JOIN r.assignment av ON av.dateTo IS NULL LEFT JOIN av.permissions p " + "WHERE r.name IN :names GROUP BY r.dbid, r.name") List<RoleWithActiveAssignmentsDTO> readByRoleNameInOnlyActiveAssignments(List<String> names);
内容的提问来源于stack exchange,提问作者Peter F
相关产品推荐
相关产品推荐

