我有两个实体:
@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
参数匹配的用户的用户名? (为什么当角色不存在时它不返回用户名?)
似乎您没有在
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
永远不会为真。