2016-09-28 1 views
1

Ich habe vier tables.entities,Implementierung ternäre Beziehung in Hibernate

  1. Benutzer
  2. Projekt
  3. Rolle
  4. UserProjectRole

Mein Szenario oder Beziehung ist, in einem Projekt, Ein Benutzer hat viele Rollen. Ich bin verwirrt, um Beziehungen in obigen Hibernate-Entitäten zuzuordnen. Brauchen Sie Hilfe.

Vielen Dank im Voraus.

+0

Welche Beziehung hat UserProjectRole zu anderen Entitäten? ODER Verwendung der UserProjectRole-Tabelle? –

+0

Ich verwende es, um zu speichern, welcher Benutzer welche Rolle in welchem ​​Projekt hat. Zum Beispiel hat Benutzer "A" die Rolle "ScrumMaster" im Projekt "P". –

+0

Kann ein Benutzer mehrere Rollen in einem Projekt haben? z.B. Benutzer A ist sowohl Scrummaster als auch Entwickler in Projekt P? – dcsohl

Antwort

1

Es gibt viele Möglichkeiten, eine so genannte ternäre Beziehung mit Hibernate zu implementieren, indem entweder "simple" map oder die Verknüpfung mithilfe einer zwischengeschalteten Entität/Tabelle implementiert wird. Ihre Anwendungsfälle entscheiden, welcher der richtige ist. Es hängt davon ab, wie die Daten gespeichert sind und wie oft Sie sie lesen. Auch das Reporting ist ein wichtiger Anwendungsfall.

Wenn Sie viele Benutzer - Projekt - Rollenkombinationen zulassen möchten, ist eine Zuordnung (z. B. auf der Benutzerentität) nicht wirklich geeignet, da Ihr Schlüssel entweder das Projekt oder die Rolle wäre und ein Schlüssel nur einmal angezeigt werden könnte. Trotzdem sollte jeder Beziehungseintrag in Ihrem System eindeutig sein, so dass ich in diesem Fall die Zwischentabelle mit mindestens einer eindeutigen Einschränkung betrachten würde.

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 

} 

Weiteres (desto besser) Ansatz wäre Ihre Beziehung Objektkennung als Verbundschlüssel zu verwenden:

Die „quick and dirty“ Art und Weise würde ein Unternehmen wie sein. Dies ist etwas ausführlicher, aber Sie benötigen keinen zusätzlichen Ersatzschlüssel, damit Ihre Join-Tabelle sauberer ist.

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; 
     } 

    } 

} 

Das Mapping auch wirklich einfach ist, sind die einzigen außergewöhnliche Teile der @JoinColumn(name = "...Id", insertable = false, updatable = false) Ergänzungen. Damit können Sie Ihre zugeordnete Entität (für Navigationszwecke) verwenden, ohne sie zweimal zu speichern.

Verwandte Themen