JPA双向实体:在查询父实体时仅选择子实体的子集
Posted
技术标签:
【中文标题】JPA双向实体:在查询父实体时仅选择子实体的子集【英文标题】:JPA bidirectional entities: Select only a sub-set of child entities while query for Parent entities 【发布时间】:2021-05-01 09:34:45 【问题描述】:假设我有一个Parent
,它有一个Set
的Child
实体。
@Entity
public class Parent
//...
@OneToMany(mappedBy = "parent")
Set<Child> children = new HashSet<>();
//...
@Entity
public class Child
//...
@ManyToOne
@JoinColumn(name = "parent_id", nullable = false)
private Parent parent;
//...
private Integer someProperty;
我想选择Parent
实体列表,其中Child
有一些规范。为此,我使用这样的查询:
@Query(value = "select distinct p from Parent p left join p.children c where c.someProperty > ?1")
通过这个查询,我拥有他们的孩子拥有的所有Parent
实体someProperty > someValue
。
问题在于,在service
类中,当我获取Parent
实例的子代时,Hibernate
会从数据库中加载所有子代,而我只希望子集查询中满足该规范的子代父母的孩子。
【问题讨论】:
【参考方案1】:你可以使用filters:
@FilterDef(
name="childrenFilter",
parameters=@ParamDef(name="parameter", type="int" ))
@Entity
public class Parent
//...
@FilterJoinTable(
name="childrenFilter",
condition="childProperty > :parameter")
@OneToMany(mappedBy = "parent")
Set<Child> children = new HashSet<>();
//...
如果你想使用过滤器,你需要启用它们:
String jpql = "select distinct p from Parent p left join p.children c where c.someProperty > ?1";
entityManager
.unwrap( Session.class )
.enableFilter( "childrenFilter" )
.setParameter( "parameter", 11)
.createQuery(jpql, Parent.class)
.setParameter(1, 11)
.getResultList();
您可以在查询后禁用过滤器:
entityManager
.unwrap( Session.class )
.disableFilter( "childrenFilter" );
【讨论】:
谢谢!两个问题: 1- 如何在 Spring Boot 中使用过滤器实现查询?如何启用/禁用过滤器?例如在后台服务中我们不需要过滤器。 我不知道 Spring Boot 开箱即用地处理它们。但是它们只有在您使用实体管理器启用它们时才有效,因此您只能在运行查询之前启用它们并在之后禁用它们以上是关于JPA双向实体:在查询父实体时仅选择子实体的子集的主要内容,如果未能解决你的问题,请参考以下文章
是否有 JPA / JPQL 查询来搜索春季作为 JSON 传递的实体子集?