wake-up-neo.com

JPA-Anmerkung "@JoinTable"

In welchem ​​Fall verwenden Sie JPA @JoinTable Anmerkung?

126
kostas trichas

EDIT 2017-04-29 : Wie von einigen Kommentatoren erwähnt, benötigt das Beispiel JoinTable das mappedBy Anmerkungsattribut. Tatsächlich weigern sich neuere Versionen von Hibernate, mit dem folgenden Fehler gestartet zu werden:

org.hibernate.AnnotationException: 
   Associations marked as mappedBy must not define database mappings 
   like @JoinTable or @JoinColumn

Nehmen wir an, Sie haben eine Entität mit dem Namen Project und eine andere Entität mit dem Namen Task und jedes Projekt kann viele Aufgaben haben.

Sie können das Datenbankschema für dieses Szenario auf zwei Arten entwerfen.

Die erste Lösung besteht darin, eine Tabelle mit dem Namen Project und eine andere Tabelle mit dem Namen Task zu erstellen und der Aufgabentabelle mit dem Namen project_id Eine Fremdschlüsselspalte hinzuzufügen:

Project      Task
-------      ----
id           id
name         name
             project_id

Auf diese Weise kann das Projekt für jede Zeile in der Aufgabentabelle ermittelt werden. Wenn Sie diesen Ansatz verwenden, benötigen Sie in Ihren Entitätsklassen keine Verknüpfungstabelle:

@Entity
public class Project {

   @OneToMany(mappedBy = "project")
   private Collection<Task> tasks;

}

@Entity
public class Task {

   @ManyToOne
   private Project project;

}

Die andere Lösung besteht darin, eine dritte Tabelle zu verwenden, z. Project_Tasks Und speichern Sie die Beziehung zwischen Projekten und Aufgaben in dieser Tabelle:

Project      Task      Project_Tasks
-------      ----      -------------
id           id        project_id
name         name      task_id

Die Tabelle Project_Tasks Heißt "Join Table". Um diese zweite Lösung in JPA zu implementieren, müssen Sie die Annotation @JoinTable Verwenden. Um beispielsweise eine unidirektionale Eins-zu-Viele-Zuordnung zu implementieren, können wir unsere Entitäten als solche definieren:

Project Entität:

@Entity
public class Project {

    @Id
    @GeneratedValue
    private Long pid;

    private String name;

    @JoinTable
    @OneToMany
    private List<Task> tasks;

    public Long getPid() {
        return pid;
    }

    public void setPid(Long pid) {
        this.pid = pid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Task> getTasks() {
        return tasks;
    }

    public void setTasks(List<Task> tasks) {
        this.tasks = tasks;
    }
}

Task Entität:

@Entity
public class Task {

    @Id
    @GeneratedValue
    private Long tid;

    private String name;

    public Long getTid() {
        return tid;
    }

    public void setTid(Long tid) {
        this.tid = tid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

Dadurch wird die folgende Datenbankstruktur erstellt:

ER Diagram 1

Mit der Annotation @JoinTable Können Sie auch verschiedene Aspekte der Verknüpfungstabelle anpassen. Hatten wir beispielsweise die Eigenschaft tasks wie folgt kommentiert:

@JoinTable(
        name = "MY_JT",
        joinColumns = @JoinColumn(
                name = "PROJ_ID",
                referencedColumnName = "PID"
        ),
        inverseJoinColumns = @JoinColumn(
                name = "TASK_ID",
                referencedColumnName = "TID"
        )
)
@OneToMany
private List<Task> tasks;

Die resultierende Datenbank wäre geworden:

ER Diagram 2

Wenn Sie ein Schema für eine Viele-zu-Viele-Zuordnung erstellen möchten, ist die Verwendung einer Verknüpfungstabelle die einzige verfügbare Lösung.

311
Behrang

Es ist die einzige Lösung, um eine ManyToMany-Verknüpfung zuzuordnen: Sie benötigen eine Verknüpfungstabelle zwischen den beiden Entitätstabellen, um die Verknüpfung zuzuordnen.

Es wird auch für OneToMany-Verknüpfungen (normalerweise unidirektionale Verknüpfungen) verwendet, wenn Sie keinen Fremdschlüssel in die Tabelle der Mehrfachseite einfügen möchten, um ihn so unabhängig von der einen Seite zu halten.

Suchen Sie in der Dokumentation zum Ruhezustand nach @JoinTable, um Erklärungen und Beispiele zu erhalten.

13
JB Nizet

Es ist auch sauberer, @JoinTable wenn eine Entität das Kind in mehreren Eltern-Kind-Beziehungen mit verschiedenen Elterntypen sein könnte. Stellen Sie sich vor, eine Aufgabe könnte das Kind von Projekt, Person, Abteilung, Studie und Prozess sein, um Behrangs Beispiel zu folgen.

Sollte die Tabelle task 5 Fremdschlüsselfelder nullable enthalten? Ich denke nicht...

13
HDave

Damit können Sie mit vielen zu vielen Beziehungen umgehen. Beispiel:

Table 1: post

post has following columns
____________________
|  ID     |  DATE   |
|_________|_________|
|         |         |
|_________|_________|

Table 2: user

user has the following columns:

____________________
|     ID  |NAME     |
|_________|_________|
|         |         |
|_________|_________|

Mit Join Table können Sie ein Mapping erstellen, indem Sie Folgendes verwenden:

@JoinTable(
  name="USER_POST",
  [email protected](name="USER_ID", referencedColumnName="ID"),
  [email protected](name="POST_ID", referencedColumnName="ID"))

erstellt eine Tabelle:

____________________
|  USER_ID| POST_ID |
|_________|_________|
|         |         |
|_________|_________|
4
slal