如何使用Spring Data Jpa根据条件获取父项及其所有子项?

huangapple go评论72阅读模式
英文:

How to fetch parent and all its children with criteria using Spring Data Jpa?

问题

我有一个类似下面的 ParentChild 实体 -

class Parent {
  Long id;
  List<Child> children;
}

class Child {
  Long id;
  String status; // ACTIVE 或 INACTIVE
  Parent parent;
}

我想获取具有 status=ACTIVE 属性的 parent 及其所有 children

public interface ParentRepository<Parent, Long> {
     Parent findByIdAndChildStatus(@Param("id") id, @Param("childStatus") status);
    }

问题是 -

  1. 获取仅有 ACTIVE 的子元素的最简单方法是什么?
  2. 是否可以在 Child 实体的 status 属性上设置 ACTIVE 查询条件,以默认获取仅处于活动状态的子实体?
  3. 类似上面的查询方法会起作用吗?
英文:

I have a Parent and Child entities like below -

class Parent {
  Long id;
  List&lt;Child&gt; children;
}

class Child {
  Long id;
  String status; // ACTIVE or INACTIVE
  Parent parent;
}

I would like to fetch the parent along with all its children having status=ACTIVE property.

public interface ParentRepository&lt;Parent, Long&gt; {
     Parent findByIdAndChildStatus(@Param(&quot;id&quot;) id, @Param(&quot;childStatus&quot;) status);
    }

Question is -

  1. What is the easiest way to fetch only ACTIVE children?
  2. Is it possible to set ACTIVE query condition on the Child entity's
    status property to fetch only active child entities by default?
  3. Will something like above query method work?

答案1

得分: 1

  1. 请参见下方
  2. 使用Spring注解本身是不可能的,但您可以通过Hibernate的@Where实现:
@Entity
@Getter
@Setter
public class Parent {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;

    @Where(clause = "status='ACTIVE'")
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
    private List<Child> children;
}
  1. 您的查询方法不起作用,Spring Data不会理解方法名称。要使其工作,Child实体的名字应该是复数形式:
public interface ParentRepository extends CrudRepository<Parent, Long> {

    Parent findByIdAndChildrenStatus(Long id, String status);

}

不幸的是,该方法的含义会有一些不同于预期。它意味着:获取id为id的Parent,其具有状态为status的Child。生成的查询如下所示:

SELECT parent0_.id AS id1_1_
FROM parent parent0_
LEFT OUTER JOIN child children1_ ON parent0_.id=children1_.parent_id
WHERE parent0_.id=? AND children1_.status=?
英文:
  1. See below
  2. It's not possible with Spring annotations alone, but you can achieve it with Hibernate's @Where:
@Entity
@Getter
@Setter
public class Parent {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;

    @Where(clause = &quot;status=&#39;ACTIVE&#39;&quot;)
    @OneToMany(mappedBy = &quot;parent&quot;, cascade = CascadeType.ALL)
    private List&lt;Child&gt; children;
}
  1. Your query method would not work, Spring Data wouldn't understand the method name. To make it work, the Child entity would need to be in the plural form:
public interface ParentRepository extends CrudRepository&lt;Parent, Long&gt; {

    Parent findByIdAndChildrenStatus(Long id, String status);

}

Unfortunately, the meaning of the method would be a bit different than expected. It would mean: get Parent with the id id and having a Child with the status status. The generated query looks as follows:

SELECT parent0_.id AS id1_1_
FROM parent parent0_
LEFT OUTER JOIN child children1_ ON parent0_.id=children1_.parent_id
WHERE parent0_.id=? AND children1_.status=?

huangapple
  • 本文由 发表于 2020年9月7日 23:16:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/63780305.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定