Adnotacja JPA "@JoinTable"

W jakim przypadku używasz adnotacji JPA @JoinTable?

Author: Manuel Drieschmanns, 2011-03-30

4 answers

EDIT 2017-04-29: jak zauważyli niektórzy komentatorzy, przykład JoinTable nie wymaga atrybutu adnotacji mappedBy. W rzeczywistości, najnowsze wersje Hibernate odmawiają uruchomienia przez wydrukowanie następującego błędu:

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

Załóżmy, że masz podmiot o nazwie Project i inny podmiot o nazwie Task i każdy projekt może mieć wiele zadań.

Możesz zaprojektować schemat bazy danych dla tego scenariusza na dwa sposoby.

Pierwszym rozwiązaniem jest Utwórz tabelę o nazwie Project i inną tabelę o nazwie Task i dodaj kolumnę z kluczem obcym do tabeli zadań o nazwie project_id:

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

W ten sposób będzie można określić projekt dla każdego wiersza w tabeli zadań. Jeśli używasz tego podejścia, w klasach encji nie będziesz potrzebował tabeli join:

@Entity
public class Project {

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

}

@Entity
public class Task {

   @ManyToOne
   private Project project;

}

Innym rozwiązaniem jest użycie trzeciej tabeli, np. Project_Tasks, i zapisanie relacji między projektami i zadaniami w tej tabeli:

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

Tabela Project_Tasks nazywa się / align = "left" / Aby zaimplementować to drugie rozwiązanie w JPA, musisz użyć adnotacji @JoinTable. Na przykład, aby zaimplementować jednokierunkowe skojarzenie jeden do wielu, możemy zdefiniować nasze byty jako takie:

Project entity:

@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 entity:

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

}

Spowoduje to utworzenie następującej struktury bazy danych:

Na

Adnotacja @JoinTable pozwala również dostosować różne aspekty tabeli join. Na przykład, czy opisaliśmy właściwość tasks w następujący sposób:

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

Wynikowa baza danych stała by się:

Na

Wreszcie, jeśli chcesz utworzyć schemat dla skojarzenia wielu do wielu, użycie tabeli join jest jedynym dostępnym rozwiązaniem.

 276
Author: Behrang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-10 00:55:40

Jest to jedyne rozwiązanie do mapowania wielu asocjacji : do mapowania asocjacji potrzebujesz tabeli join pomiędzy tabelami to entities.

Jest również używany do skojarzeń OneToMany (Zwykle jednokierunkowych), gdy nie chcesz dodawać klucza obcego w tabeli wielu stron, a tym samym zachować niezależność od jednej strony.

Wyszukaj @JoinTable w dokumentacji hibernate w celu uzyskania wyjaśnień i przykładów.

 13
Author: JB Nizet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-29 21:08:45

Jest również czystsze użycie @JoinTable, gdy jednostka może być dzieckiem w kilku relacjach rodzic / dziecko z różnymi typami rodziców. aby nawiązać do przykładu Behranga, wyobraź sobie, że zadanie może być dzieckiem projektu, osoby, działu, badania i procesu.

Czy tabela task powinna zawierać 5 nullable pól klucza obcego? Nie sądzę...

 13
Author: HDave,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-02 15:24:34

Pozwala obsługiwać wiele do wielu relacji. Przykład:

Table 1: post

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

Table 2: user

user has the following columns:

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

Join Table pozwala utworzyć mapowanie za pomocą:

@JoinTable(
  name="USER_POST",
  joinColumns=@JoinColumn(name="USER_ID", referencedColumnName="ID"),
  inverseJoinColumns=@JoinColumn(name="POST_ID", referencedColumnName="ID"))

Utworzy tabelę:

____________________
|  USER_ID| POST_ID |
|_________|_________|
|         |         |
|_________|_________|
 3
Author: slal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-02 15:36:42