JPQL查询以获取基于用户ID的用户的所有角色。

huangapple go评论80阅读模式
英文:

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 = &quot;USERS&quot;)
public class User {
    @Id
    @Column(name = &quot;USER_ID&quot;)
    private String userId;
    @Basic
    @Column(name = &quot;EMAIL&quot;)
    private String email;
   
	@OneToMany(fetch = LAZY, mappedBy = &quot;user&quot;)
    private Set&lt;UserRole&gt; userRoles;
}

Role:

@Data
@Entity
@Table(NAME = &quot;ROLES&quot;)
public class Role {
    @Id
    @Column(name = &quot;ROLE_ID&quot;)
    private String roleId;
    @Basic
    @Column(name = &quot;NAME&quot;)
    private String name;
   
	@OneToMany(fetch = LAZY, mappedBy = &quot;role&quot;)
    private Set&lt;UserRole&gt; userRoles;
}

UserRole:

@Data
@Entity
@IdClass(UserRolePK.class)
@Table(NAME = &quot;USER_ROLES&quot;)
public class UserRole {
    @Id
    @Column(name = &quot;USER_ID&quot;)
    private String userId; 

	@Id
    @Column(name = &quot;ROLE_ID&quot;)
    private String roleId;
	
    @ManyToOne(fetch = LAZY)
    @JoinColumn(name = &quot;USER_ID&quot;, insertable = false, updatable = false)
    private User user;

    @ManyToOne(fetch = LAZY)
    @JoinColumn(name = &quot;ROLE_ID&quot;, 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(
    &quot;select u &quot; +
    &quot;from User u &quot; +
    &quot;left join fetch u.userRoles &quot;+
    &quot;where u.userId = :id &quot;
)
List&lt;User&gt; getUsersByIdAndRoles(@Param(&quot;id&quot;) 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 = &quot;USERS&quot;)
public class User {
    @Id
    @Column(name = &quot;USER_ID&quot;)
    private String userId;

    @Column(name = &quot;EMAIL&quot;)
    private String email;
   
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = &quot;USER_ROLES&quot;,
              joinColumns = @JoinColumn(name = &quot;USER_ID&quot;),
              inverseJoinColumns = @JoinColumn(name = &quot;ROLE_ID&quot;))
    private Set&lt;Role&gt; roles;
}

@Data
@Entity
@Table(NAME = &quot;ROLES&quot;)
public class Role {
    @Id
    @Column(name = &quot;ROLE_ID&quot;)
    private String roleId;

    @Column(name = &quot;NAME&quot;)
    private String name;
   
    @ManyToMany(fetch = FetchType.LAZY, mappedBy = &quot;roles&quot;)
    private Set&lt;User&gt; 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(
    &quot;select u &quot; +
    &quot;from User u &quot; +
    &quot;left join fetch u.roles &quot;+
    &quot;where u.userId = :id &quot;
)
List&lt;User&gt; getUsersWithFetchedRoles(@Param(&quot;id&quot;) 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.

huangapple
  • 本文由 发表于 2020年10月18日 18:24:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/64412210.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定