ManyToManyToMany - 使用 Hibernate 注释连接三个表

Raw*_*awr 5 java annotations hibernate jpa

起初我认为这个解决方案可能会解决我的问题:

@Entity
public class User {

    @JoinTable(name = "user_permission",
        joinColumns = @JoinColumn(name = "user_id"),
        inverseJoinColumns = @JoinColumn(name = "permission_id"))
    @MapKeyJoinColumn(name = "project_id")
    @ElementCollection
    private Map<Project, Permission> permissions = new HashMap<>();

}

@Entity
public class Project {
    ...
}

@Entity
public class Permission {
    ...
}
Run Code Online (Sandbox Code Playgroud)

但在这个实现中,Permission每个Project. 我想完成为项目设置多个权限的能力,以便以下内容为真:

| user_id | project_id | permission_id |
|---------|------------|---------------|
| 1       | 1          | 1             |
|---------|------------|---------------|
| 1       | 1          | 2             |
|---------|------------|---------------|
| 1       | 2          | 1             |
|---------|------------|---------------|
| 1       | 2          | 2             |
|---------|------------|---------------|
| 2       | 1          | 1             |
|---------|------------|---------------|
| 2       | 1          | 2             |
|---------|------------|---------------|
| 2       | 2          | 1             |
|---------|------------|---------------|
| 2       | 2          | 2             |
Run Code Online (Sandbox Code Playgroud)

Gré*_*mer 5

您可以使用专用于关系表的实体。例如,这是我们用它们自己的属性声明关系的方式。
这将导致以下实现:

@Entity
@IdClass(PermissionAssignation.class)
public class PermissionAssignation {

     @Id
     @ManyToOne
     @JoinColumn(name="user_id")
     private User user;

     @Id
     @ManyToOne
     @JoinColumn(name="project_id")
     private Project project;

     @Id
     @ManyToOne
     @JoinColumn(name="permission_id")
     private Permission permission;
     ...
}
Run Code Online (Sandbox Code Playgroud)

我使用了在这篇文章中找到的解决方案:Hibernate and no PK

它解释了如何使用字段创建 PK(我没有测试它)。如果它不起作用,你最好使用一个EmbeddedId类。

如果您希望您的关系是双向的,则可以使用 a Set<PermissionAssignation>(or List,根据您的喜好/需要):

 @Entity
 public class User {

      @OneToMany(mappedBy="user")
      private Set<PermissionAssignation> permissions;

 }
Run Code Online (Sandbox Code Playgroud)