2016-09-28 91 views
1

三元關係,我有四個tables.entities,實現在休眠

  1. 用戶
  2. 項目
  3. 角色
  4. UserProjectRole

我的情況或關係,在一個項目中,一個用戶有很多角色。 我很困惑地在上面的hibernate實體中映射關係。 需要一些幫助。

在此先感謝。

+0

UserProjectRole與其他實體的關係如何。 OR UserProjectRole表的使用情況? –

+0

我將用它來存儲哪個用戶在哪個項目中具有哪個角色。例如,用戶「A」在項目「P」中具有「ScrumMaster」角色。 –

+0

用戶可以在一個項目中擁有多個角色嗎?例如用戶A既是Scrummaster又是項目P的開發人員? – dcsohl

回答

1

有很多方法可以實現與Hibernate的所謂三元關係,或者利用"simple" map或者使用中間實體/表實現關聯。你的用例決定哪個是正確的。這取決於數據如何存儲以及您將如何(經常)讀取它。報告也是一個重要的用例。

如果您希望允許許多用戶 - 項目 - 角色組合,則映射(例如用戶實體上的映射)並不十分合適,因爲您的密鑰可能是項目或角色,並且密鑰只能出現一次。儘管如此,每個關係條目在系統中都應該是唯一的,所以在這種情況下,我傾向於至少具有一些獨特約束的中間表。

的「快速和骯髒」的方式將是一個實體,如:

import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.Id; 
import javax.persistence.ManyToOne; 
import javax.persistence.Table; 
import javax.persistence.UniqueConstraint; 

@Entity 
@Table(uniqueConstraints = @UniqueConstraint(columnNames={"user_id", "project_id", "role_id"})) 
public class UserProjectRoleSimple { 

    @Id 
    @GeneratedValue 
    private Long id; 

    @ManyToOne 
    private User user; 
    @ManyToOne 
    private Project project; 
    @ManyToOne 
    private Role role; 

    // you also need constructors, getters, equals, hashcode and stuff 

} 

另一個(更好的)方法是使用關係對象標識符作爲複合鍵。這有點冗長,但你不需要額外的代理鍵,所以你的連接表更乾淨。

import java.io.Serializable; 

import javax.persistence.Embeddable; 
import javax.persistence.EmbeddedId; 
import javax.persistence.Entity; 
import javax.persistence.JoinColumn; 
import javax.persistence.ManyToOne; 
import javax.validation.constraints.NotNull; 

import org.hibernate.annotations.Immutable; 

@Entity 
@Immutable 
public class UserProjectRole { 

    protected UserProjectRole() { 
    } 

    public UserProjectRole(final User user, final Project project, final Role role) { 
     this.userProjectRoleId = new UserProjectRoleId(user, project, role); 
     this.user = user; 
     this.project = project; 
     this.role = role; 
    } 

    @EmbeddedId 
    protected UserProjectRoleId userProjectRoleId; 

    @ManyToOne 
    @JoinColumn(name = "userId", insertable = false, updatable = false) 
    private User user; 
    @ManyToOne 
    @JoinColumn(name = "projectId", insertable = false, updatable = false) 
    private Project project; 
    @ManyToOne 
    @JoinColumn(name = "roleId", insertable = false, updatable = false) 
    private Role role; 

    public User getUser() { 
     return user; 
    } 

    public Project getProject() { 
     return project; 
    } 

    public Role getRole() { 
     return role; 
    } 

    @Embeddable 
    static class UserProjectRoleId implements Serializable { 

     private static final long serialVersionUID = 7994974851694559677L; 

     @NotNull 
     private Long userId; 
     @NotNull 
     private Long projectId; 
     @NotNull 
     private Long roleId; 

     protected UserProjectRoleId() { 
     } 

     protected UserProjectRoleId(final User user, final Project project, final Role role) { 
      this.userId = user.getId(); 
      this.projectId = project.getId(); 
      this.roleId = role.getId(); 
     } 

     @Override 
     public int hashCode() { 
      final int prime = 31; 
      int result = 1; 
      result = prime * result + ((projectId == null) ? 0 : projectId.hashCode()); 
      result = prime * result + ((roleId == null) ? 0 : roleId.hashCode()); 
      result = prime * result + ((userId == null) ? 0 : userId.hashCode()); 
      return result; 
     } 

     @Override 
     public boolean equals(Object obj) { 
      if (this == obj) 
       return true; 
      if (obj == null) 
       return false; 
      if (getClass() != obj.getClass()) 
       return false; 
      UserProjectRoleId other = (UserProjectRoleId) obj; 
      if (projectId == null) { 
       if (other.projectId != null) 
        return false; 
      } else if (!projectId.equals(other.projectId)) 
       return false; 
      if (roleId == null) { 
       if (other.roleId != null) 
        return false; 
      } else if (!roleId.equals(other.roleId)) 
       return false; 
      if (userId == null) { 
       if (other.userId != null) 
        return false; 
      } else if (!userId.equals(other.userId)) 
       return false; 
      return true; 
     } 

    } 

} 

該映射也很簡單,只有非凡的部分是@JoinColumn(name = "...Id", insertable = false, updatable = false)增加。有了它,您可以使用您的映射實體(用於導航目的),而不需要存儲兩次。