英文:
JPQL query to fetch all roles of user based on user id
问题
在我的项目中,用户(User)和角色(Role)之间存在多对多关系。因此,我还有一个新实体 UserRole
,用于连接这两个实体。
它的结构如下所示:
用户(User):
@Data
@Entity
@Table(name = "USERS")
public class User {
@Id
@Column(name = "USER_ID")
private String userId;
@Basic
@Column(name = "EMAIL")
private String email;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
private Set<UserRole> userRoles;
}
角色(Role):
@Data
@Entity
@Table(name = "ROLES")
public class Role {
@Id
@Column(name = "ROLE_ID")
private String roleId;
@Basic
@Column(name = "NAME")
private String name;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "role")
private Set<UserRole> userRoles;
}
用户角色(UserRole):
@Data
@Entity
@IdClass(UserRolePK.class)
@Table(name = "USER_ROLES")
public class UserRole {
@Id
@Column(name = "USER_ID")
private String userId;
@Id
@Column(name = "ROLE_ID")
private String roleId;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "USER_ID", insertable = false, updatable = false)
private User user;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ROLE_ID", insertable = false, updatable = false)
private Role role;
}
在这种情况下,用户可以具有多个角色。
问题: 如何使用一条查询(JPQL)按用户ID(userId)获取他所分配的所有角色,并获得用户及其分配的所有角色的列表?
我知道我可以首先按ID获取用户,然后可以根据 UserRole 表分别获取角色。
但我希望在一次查询中完成。我希望得到具有角色列表的用户。
英文:
In my project I have many-to-many relationship between User and Role. For this reason I have also new entity UserRole
which connects this two entities.
It looks like this:
User:
@Data
@Entity
@Table(NAME = "USERS")
public class User {
@Id
@Column(name = "USER_ID")
private String userId;
@Basic
@Column(name = "EMAIL")
private String email;
@OneToMany(fetch = LAZY, mappedBy = "user")
private Set<UserRole> userRoles;
}
Role:
@Data
@Entity
@Table(NAME = "ROLES")
public class Role {
@Id
@Column(name = "ROLE_ID")
private String roleId;
@Basic
@Column(name = "NAME")
private String name;
@OneToMany(fetch = LAZY, mappedBy = "role")
private Set<UserRole> userRoles;
}
UserRole:
@Data
@Entity
@IdClass(UserRolePK.class)
@Table(NAME = "USER_ROLES")
public class UserRole {
@Id
@Column(name = "USER_ID")
private String userId;
@Id
@Column(name = "ROLE_ID")
private String roleId;
@ManyToOne(fetch = LAZY)
@JoinColumn(name = "USER_ID", insertable = false, updatable = false)
private User user;
@ManyToOne(fetch = LAZY)
@JoinColumn(name = "ROLE_ID", insertable = false, updatable = false)
private Role role;
}
In this scenario User can have multiple roles.
Question: How to fetch User by his id (userId) with all assigned to him Roles using one query (JPQL)?
I know I can first fetch User by id, and than I can fetched separately Roles based on UserRole table.
But I want to do that in one query. I want to have User with List of Roles.
答案1
得分: 1
可以使用fetch
关键字:
@Query(
"select u " +
"from User u " +
"left join fetch u.userRoles "+
"where u.userId = :id "
)
List<User> getUsersByIdAndRoles(@Param("id") String id)
英文:
You can use the fetch
keyword:
@Query(
"select u " +
"from User u " +
"left join fetch u.userRoles "+
"where u.userId = :id "
)
List<User> getUsersByIdAndRoles(@Param("id") String id)
答案2
得分: 1
我建议您按照以下方式更正您的映射:
@Data
@Entity
@Table(name = "USERS")
public class User {
@Id
@Column(name = "USER_ID")
private String userId;
@Column(name = "EMAIL")
private String email;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "USER_ROLES",
joinColumns = @JoinColumn(name = "USER_ID"),
inverseJoinColumns = @JoinColumn(name = "ROLE_ID"))
private Set<Role> roles;
}
@Data
@Entity
@Table(name = "ROLES")
public class Role {
@Id
@Column(name = "ROLE_ID")
private String roleId;
@Column(name = "NAME")
private String name;
@ManyToMany(fetch = FetchType.LAZY, mappedBy = "roles")
private Set<User> users;
}
这个更正只会影响到数据库模式,而不会影响到 Hibernate 映射。然后您可以按照 Andronicus 回答中的建议进行操作:
@Query(
"select u " +
"from User u " +
"left join fetch u.roles "+
"where u.userId = :id "
)
List<User> getUsersWithFetchedRoles(@Param("id") String id)
如果您继续使用当前的映射,您将无法一次获取多个关联,正如在这篇文章中所解释的那样。
关于 @ManyToMany
关联的更多细节,请参阅文档。
英文:
I would suggest you to correct your mapping in the following way:
@Data
@Entity
@Table(NAME = "USERS")
public class User {
@Id
@Column(name = "USER_ID")
private String userId;
@Column(name = "EMAIL")
private String email;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "USER_ROLES",
joinColumns = @JoinColumn(name = "USER_ID"),
inverseJoinColumns = @JoinColumn(name = "ROLE_ID"))
private Set<Role> roles;
}
@Data
@Entity
@Table(NAME = "ROLES")
public class Role {
@Id
@Column(name = "ROLE_ID")
private String roleId;
@Column(name = "NAME")
private String name;
@ManyToMany(fetch = FetchType.LAZY, mappedBy = "roles")
private Set<User> users;
}
This correction will not affect the database schema only hibernate mapping.
Then you will be able to do as suggested in the Andronicus answer:
@Query(
"select u " +
"from User u " +
"left join fetch u.roles "+
"where u.userId = :id "
)
List<User> getUsersWithFetchedRoles(@Param("id") String id)
If you stay with your current mapping you will not be able to fetch more than one association at a time as it is explained in this article.
Additional details related to the @ManyToMany
association see in the documentation.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论