多对多关系上的 Spring Data JPA 查询返回所有记录而不是匹配记录

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

我有两个实体:

@Entity
@Table(schema = "public", name = "app_user")
public class AppUser implements Serializable {
    @Id
    @Column(name = "id")
    private int id;
    
    @Column(name = "username")
    private String username;
    
    @ManyToMany()
    @JoinTable(
            name = "app_user_app_role",
            joinColumns = {
                @JoinColumn(name = "app_user_id", referencedColumnName = "id")},
            inverseJoinColumns = {
                @JoinColumn(name = "app_role_id", referencedColumnName = "id")})
    private Set<AppRole> roles;
    
}
@Entity
@Table(schema = "public", name = "app_role")
public class AppRole implements Serializable {
    @Id
    @Column(name = "id")
    private int id;
    
    @Column(name = "app_role_name")
    private String roleName;
}

连接表

app_user_app_role
有三列:“id”、“app_user_id”和“app_role_id”,其中最后两列是对应表的外键

我有以下 JpaRepository 方法:

@Repository
public interface AppUserRepository extends JpaRepository<AppUser, Integer> {
    /**
     * Get a list of usernames for users with the specified role name assigned.
     * @param roleName
     * @return 
     */
    @Query("SELECT au.username FROM AppUser au \n" +
        "INNER JOIN AppRole ar \n" +
        "WHERE ar.roleName = :roleName")
    List<String> getAppUsersWithRole(@Param("roleName") String roleName);
}

我有三个用户,“johndoe”、“sam”和“janegoodall”。我有两个角色,“用户管理员”和“测试”。 “johndoe”和“sam”都有“User Admin”角色,“sam”有“Test”角色。 “janegoodall”没有角色。

当我调用

AppUserRepository.getAppUsersWithRole("User Admin")
时,我得到了所有三个用户的用户名,而不是“johndoe”和“sam”。当我调用
AppUserRepository.getAppUsersWithRole("Test")
时,我还获得了所有三个用户的用户名,而不仅仅是“sam”。当我打电话给
AppUserRepository.getAppUsersWithRole("nonexistent role")
时,我得到了一个空列表。

当我检索个人用户记录并检查他们的 AppRole 列表时,他们都有预期的角色,所以我知道 AppUser 中的

@ManyToMany
@JoinTable
设置正确。

为什么我的 jpql 查询返回所有用户名,而不是角色与

:roleName
参数匹配的用户的用户名? (为什么当角色不存在时它不返回用户名?)

java spring spring-data-jpa many-to-many jpql
1个回答
0
投票

似乎您没有在

AppUser
声明中指定
AppRole
INNER JOIN
实体之间的关系。您应该使用
roles
实体中的
AppUser
字段来建立它:

@Repository
public interface AppUserRepository extends JpaRepository<AppUser, Integer> {
    /**
     * Get a list of usernames for users with the specified role name assigned.
     * @param roleName
     * @return 
     */
    @Query("SELECT au.username FROM AppUser au " +
        "INNER JOIN au.roles ar " +
        "WHERE ar.roleName = :roleName")
    List<String> getAppUsersWithRole(@Param("roleName") String roleName);
}

如果角色不存在,则不会返回任何行,因为

ar.roleName = :roleName
永远不会为真。

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