英文:
How to fetch parent and all its children with criteria using Spring Data Jpa?
问题
我有一个类似下面的 Parent 和 Child 实体 -
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);
    }
问题是 -
- 获取仅有 
ACTIVE的子元素的最简单方法是什么? - 是否可以在 
Child实体的status属性上设置 ACTIVE 查询条件,以默认获取仅处于活动状态的子实体? - 类似上面的查询方法会起作用吗?
 
英文:
I have a Parent and Child entities like below -
class Parent {
  Long id;
  List<Child> 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<Parent, Long> {
     Parent findByIdAndChildStatus(@Param("id") id, @Param("childStatus") status);
    }
Question is -
- What is the easiest way to fetch only 
ACTIVEchildren? - Is it possible to set ACTIVE query condition on the 
Childentity's
statusproperty to fetch only active child entities by default? - Will something like above query method work?
 
答案1
得分: 1
- 请参见下方
 - 使用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;
}
- 您的查询方法不起作用,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=?
英文:
- See below
 - 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 = "status='ACTIVE'")
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
    private List<Child> children;
}
- Your query method would not work, Spring Data wouldn't understand the method name. To make it work, the 
Childentity would need to be in the plural form: 
public interface ParentRepository extends CrudRepository<Parent, Long> {
    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=?
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论