JPA 查询用于在获取父实体时过滤嵌套实体

问题描述 投票:0回答:1

我有一个 Spring Boot 项目。这些是我的 3 个类,分别代表用户、组和成员资格(用户和具有自定义表的组之间的 @ManyToMany 关系)实体:

用户.java

@Getter
@Setter
@Builder
@AllArgsConstructor
@Entity
@Table(name = "users")
public class User extends BaseEntity {

    @Id
    @GeneratedValue
    @Column(name = "id", nullable = false)
    private Long id;

    @Column(name = "name")
    private String name;

    @OneToMany(mappedBy = "member", cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    private Set<Membership> membership;
}

组.java

@Getter
@Setter
@Builder
@AllArgsConstructor
@Entity
@Table(name = "groups")
public class Group extends BaseEntity {

    @Id
    @GeneratedValue
    @Column(name = "id", nullable = false)
    private Long id;

    private String name;

    @OneToMany(
            mappedBy = "group",
            cascade = {CascadeType.PERSIST, CascadeType.MERGE},
            fetch = FetchType.EAGER
    )
    private Set<Membership> members;
}

Membership.java

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@Entity
public class Membership extends BaseEntity {

    @Id
    @GeneratedValue
    private Long id;

    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinColumn(name = "user_id")
    private User member;

    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinColumn(name = "group_id")
    private Group group;

    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinColumn(name = "role_id")
    private Role role;

我在 3 个类上扩展的 BaseEntity 有一个布尔类型的属性elaided,用于软删除。

我遇到的问题是这样的:

  • 当我从组中删除用户时,我会得到表示用户与组之间关系的成员资格行,并将已删除标志设置为 true。但是,当所有用户都从组中删除时,我的查询不再返回该组,但我希望即使所有成员都已被删除,仍然能够看到该组。这是我使用的查询:
@Query("""
        SELECT DISTINCT g FROM Group g
        LEFT JOIN FETCH g.members m
        WHERE m.deleted = false OR m IS NULL
        """)
    Set<Group> findAllGroupsWithNonDeletedMembers(Sort sort);
  • 我尝试了不同的查询,但无法使其工作,并且同样的问题来自用户端,如果我从他所属的所有组中删除用户,则不再返回该用户。这是我用来获取用户的查询:
@Query("""
       SELECT DISTINCT u FROM User u
       LEFT JOIN u.membership m ON m.deleted = true
       """)
    List<User> findAllUsersWithNonDeletedMemberships();

所以我的问题是,我应该编写什么样的查询才能完成我想要的结果? 谢谢。

java database postgresql spring-boot jpql
1个回答
0
投票

我希望这个方法可以帮助你解决你的问题

要实现此目的,您可以修改查询以选择具有未删除成员资格的组和用户,但也包括那些没有任何成员资格的组和用户。以下是修改查询的方法:

要查找具有未删除成员的群组以及没有任何成员的群组:

@Query("""
    SELECT DISTINCT g FROM Group g
    LEFT JOIN g.members m
    WHERE m IS NULL OR (m.deleted = false AND m IS NOT NULL)
    """)
Set<Group> findAllGroupsWithNonDeletedMembers(Sort sort);

在此查询中,我们使用

LEFT JOIN
来包含组,即使它们没有任何成员或具有已删除成员资格的成员。

查找具有未删除会员资格的用户以及没有任何会员资格的用户:

@Query("""
   SELECT DISTINCT u FROM User u
   LEFT JOIN u.membership m
   WHERE m IS NULL OR (m.deleted = false AND m IS NOT NULL)
   """)
List<User> findAllUsersWithNonDeletedMemberships();

查询将返回具有未删除成员资格的用户和没有任何成员资格的用户。

如果有效请告诉我。

© www.soinside.com 2019 - 2024. All rights reserved.