最有效的方式来映射@ManyToMany关系使用JPA和Hibernate是什么?

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

What is the most efficient way to map @ManyToMany relationship with JPA and Hibernate?

问题

我只了解数据库(DB)和JPA/Hibernate的基础知识。我需要管理一个用户表,其中一个用户可以拥有多个角色。这些角色存储在一个目录表中,但在我的用户表单中,我不打算管理或修改它们,我只需要将目录中的值作为参考添加或删除到我的用户中。

我认为最好的方法是创建一个用户和角色之间的关系表来保存用户和他们的角色'User_Roles'(除非有更高效的方法)。

由于Role实体在我的应用程序的许多其他区域中用于不同的目的且与用户表无关,所以我不能修改它。

我看过很多示例,但仍然不确定哪一个适用于我的特定需求。如何使用JPA和Hibernate将我的用户及其角色映射到单个实体中?

也许下面的图像更好地描述了我的需求:
最有效的方式来映射@ManyToMany关系使用JPA和Hibernate是什么?

非常感谢您提前的回答。

英文:

I know only basics of DB and JPA/Hibernate. I have to manage a User table, where a user can have many roles. The roles are contained in a catalog table which in my User formulary i do not pretend to manage/modify, i just need the catalog values as a reference to add or delete to my user.
I think the best approach would be to create a relationship table between User and Role to hold the users and their roles 'User_Roles' (unless there is a more efficient approach).

I am not allowed to modify the Role entity since it is used for different purposes in a lot of other areas of my app that are independent of the User table.

I've seen a lot of examples but I still do not know which one exactly aplies to my specific needs. How can I map my User and its roles in a sigle Entity with JPA and Hibernate?

Maybe the next image describes better what I want:
最有效的方式来映射@ManyToMany关系使用JPA和Hibernate是什么?

Thank you very much in advance for your answers.

答案1

得分: 3

在你的情况下,你需要使用 @ManyToMany 来关联这两个表格。

应该看起来像这样:

@Entity
@Table(name = "User")
public class User { 
   ...
   @ManyToMany
   @JoinTable(name = "User_Roles", joinColumn = "id_person")
   private Set<Role> roles = new HashSet<>();
}

@Entity
@Table(name = "Role")
public class Role { 
   ...
   @ManyToMany(mappedBy = "roles")
   private Set<User> users = new HashSet<>();
}
英文:

In your case you have to use @ManyToMany to associate both tables.

That should look at this:

@Entity
@Table(name = &quot;User&quot;)
public class User { 
   ...
   @ManyToMany
   @JoinTable(name = &quot;User_Roles&quot;, joinColumn = &quot;id_person&quot;)
   private Set&lt;Role&gt; roles = new HashSet&lt;&gt;;
}

@Entity
@Table(name = &quot;Role&quot;)
public class Role { 
   ...
   @ManyToMany(mappedBy = &quot;roles&quot;)
   private Set&lt;User&gt; users = new HashSet&lt;&gt;;
}

答案2

得分: 2

你所描述的是一对多关系,但它是在 User 和连接表 User_Roles 之间的关系。由于你无法避免连接表,最好的方法是使用 @ManyToMany@JoinTable 注解来映射这个关系。记得使用 Set 而不是 List。然后你就不需要一个连接表的实体了。

你可以在这篇博客文章中找到关于这个话题的讨论。

英文:

What you're describing is a one-to-many relationship but it's between User and the joining table - User_Roles. Since there is not much you can do to avoid the joining table, the best thing would be to use @ManyToMany with @JoinTable annotations to map the relationship. Remember to use Set instead of List. You don't need an entity for the joinint table then.

You can find a discussion about this topic in this blog post.

答案3

得分: 0

根据您上面的屏幕,我理解用户可以被分配多个角色。
即一个用户可以映射到多个角色,一个角色可以映射到多个用户。

因此,用户和角色之间的关系是多对多关系。

多对多关系可以通过第三个表来实现,称为映射表。

所以,在您的示例中,我们有以下表格:

  • 用户(user)
  • 用户角色(user_roles)
  • 角色(role)

在保存时,您只需填充用户实体与所有用户角色映射实体并进行持久化。JPA 将保存所有详细信息。

在更新时,将角色分配给用户,您需要获取用户实体并通过添加新的用户角色实体来更新映射,并将即将删除的部分置空。

英文:

As per your above screen, what I understood user can be assigned more than 1 role.
i.e. 1 user can be mapped to multiple role and 1 role can be mapped to multiple users.

Hence relationship between user and role is many to many.

many to many relationship can be achieved using third table which is called mapping table.

so , we have following tables in your example :-

  • user

  • user_roles

  • role

      @Entity
     @Table(name = &quot;user&quot;)
     @JsonInclude(JsonInclude.Include.NON_NULL)
     public class User {
         @Id
         @SequenceGenerator(name = &quot;USER_ID_GENERATOR&quot;, sequenceName = &quot;USER_SEQ&quot;,
                 allocationSize = 1)
         @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = &quot;USER_ID_GENERATOR&quot;)
         @Column(name = &quot;user_id&quot;)
         private Long userId;
    
         @OneToOne
         @JoinColumn(name = &quot;persion_id&quot;)
         private person person;`
         enter code
         here`
    
         @Basic
         @Column(name = &quot;date&quot;)
         private Date date;
    
         @Basic
         @Column(name = &quot;observations&quot;)
         private String observations;
    
         @Basic
         @Column(name = &quot;text&quot;)
         private String text;
    
         @JsonIgnore
         @OneToMany(mappedBy = &quot;user&quot;, cascade = CascadeType.ALL)
         private List&lt;UserRoles&gt; users = new ArrayList&lt;&gt;();
    
     }
    

    @Entity
    @Table(name = "role")
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public class Role {

     @Id
     @SequenceGenerator(name = &quot;ROLE_ID_GENERATOR&quot;, sequenceName = &quot;ROLE_SEQ&quot;,
             allocationSize = 1)
     @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = &quot;ROLE_ID_GENERATOR&quot;)
     @Column(name = &quot;role_id&quot;)
     private Long roleId;
    
     @Basic
     @Column(name = &quot;id1&quot;)
     private Long idOne;
    
     @Basic
     @Column(name = &quot;id1&quot;)
     private Long idTwo;
    
     @Basic
     @Column(name = &quot;id1&quot;)
     private Long idThree;
    
     @Basic
     @Column(name = &quot;text&quot;)
     private String text;
    
     @JsonIgnore
     @OneToMany(mappedBy = &quot;role&quot;, cascade = CascadeType.ALL)
     private List&lt;UserRoles&gt; users = new ArrayList&lt;&gt;();
    

    }

    @Entity
    @Getter
    @Setter
    @Table(name = "user_roles")
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @Audited
    public class UserRoles {

     private static final long serialVersionUID = 1L;
    
     @EmbeddedId
     UserRolesKey userRoleId;
    
     @JsonIgnore
     @ManyToOne(fetch = FetchType.LAZY)
     @MapsId(&quot;role_id&quot;)
     @JoinColumn(name = &quot;role_id&quot;)
     Roles role;
    
     @JsonIgnore
     @ManyToOne(fetch = FetchType.LAZY)
     @MapsId(&quot;user_id&quot;)
     @JoinColumn(user_id)
     User user;
    
     @PrePersist
     private void prePersist() {
         super.onPrePersist();
         if (this.getId() == null) {
             UserRolesKey mapKey = new UserRolesKey();
             mapKey.setRoleId(this.getRole().getRoleId());
             mapKey.setUserRoleId(this.getUser().getUserId());
             this.setId(mapKey);
         }
     }
    

    }

While saving you just need to populate user entity with all the uaerRoles mapping entity and persist it. jpa will save all the details.

while updating role assign to user you need to fetch the user entity and update the mapping by adding new userRoles entity and nullifying the while is going to be removed.

huangapple
  • 本文由 发表于 2020年8月4日 18:16:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/63244754.html
匿名

发表评论

匿名网友

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

确定