2016-09-28 5 views
1

で三元関係を実装する、私は4 tables.entitiesを持って休止状態

  1. ユーザー
  2. プロジェクト
  3. UserProjectRole

私のシナリオや関係1つのプロジェクトでは、ある

  • 役割、 1人のユーザーには多くの役割があります。 上記の休止状態のエンティティの関係をマップするのは混乱します。 助けが必要です。

    ありがとうございます。

  • +0

    UserProjectRoleと他のエンティティとの関係はどのようなものですか。またはUserProjectRoleテーブルの使用? –

    +0

    私はそれを使って、どのユーザがどのプロジェクトにどのような役割を持っているかを保存します。たとえば、ユーザー "A"は、プロジェクト "P"で役割 "ScrumMaster"を持っています。 –

    +0

    ユーザはプロジェクト内で複数のロールを持つことができますか?例えばユーザーAはプロジェクトPのscrummasterと開発者の両方ですか? – dcsohl

    答えて

    1

    Hibernateと呼ばれる、いわゆる"simple" mapを利用するか、中間のエンティティ/テーブルを使用して関連付けを実装する、という3つの関係を実装する方法はたくさんあります。あなたのユースケースはどちらが正しいかを決定します。それは、データがどのように格納され、どのように(しばしば)それを読むかによって異なります。また、レポートは重要な使用例です。

    多くのユーザプロジェクトロールの組み合わせを許可したい場合、あなたのキーはおそらくプロジェクトまたはロールのいずれかになり、キーは一度しか表示されないため、マップ(たとえば、ユーザーエンティティ上)は実際には適切ではありません。それにもかかわらず、すべてのリレーションエントリはシステム内で一意でなければならないので、この場合、私は少なくともいくつかのユニーク制約を持つ中間テーブルになりがちです。

    「間に合わせ」の方法は、のような実体のようになります。

    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)追加されています。これで、マッピングされたエンティティをナビゲーション目的で2回保存せずに使用できます。