W jakim przypadku używasz @JoinTable
adnotacji JPA ?
źródło
W jakim przypadku używasz @JoinTable
adnotacji JPA ?
EDYCJA 2017-04-29 : Jak zauważyli niektórzy komentatorzy, JoinTable
przykład nie potrzebuje mappedBy
atrybutu adnotacji. W rzeczywistości najnowsze wersje Hibernacji odmawiają uruchomienia, wyświetlając następujący błąd:
org.hibernate.AnnotationException:
Associations marked as mappedBy must not define database mappings
like @JoinTable or @JoinColumn
Załóżmy, że masz jednostkę o nazwie Project
i inną o nazwie, Task
a każdy projekt może mieć wiele zadań.
Schemat bazy danych można zaprojektować dla tego scenariusza na dwa sposoby.
Pierwszym rozwiązaniem jest utworzenie tabeli o nazwie Project
i innej tabeli o nazwie Task
i dodanie kolumny klucza obcego 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 łączenia:
@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 np. Trzeciej tabeli 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
Project_Tasks
Tabela nazywa się „Join Table”. Aby wdrożyć to drugie rozwiązanie w JPA, musisz użyć @JoinTable
adnotacji. Na przykład, aby zaimplementować jednokierunkowe powiązanie jeden do wielu, możemy zdefiniować nasze jednostki jako takie:
Project
jednostka:
@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
jednostka:
@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:
@JoinTable
Adnotacji pozwala również dostosować różne aspekty tabeli sprzężenia. Na przykład, gdybyśmy opisali tasks
właściwość w ten 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;
Powstała baza danych stałaby się:
Wreszcie, jeśli chcesz utworzyć schemat dla asocjacji wiele do wielu, użycie tabeli łączenia jest jedynym dostępnym rozwiązaniem.
@JoinTable/@JoinColumn
w tym samym polu można umieścić adnotacjęmappedBy
. Tak więc poprawnym przykładem powinno być trzymaniemappedBy
wProject
środku i przejście@JoinColumn
doTask.project
(lub odwrotnie)Project_Tasks
potrzebujename
odTask
a także, co staje się trzy kolumny:project_id
,task_id
,task_name
, jak to osiągnąć?Caused by: org.hibernate.AnnotationException: Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn:
Jest również bardziej przejrzysty w użyciu,
@JoinTable
gdy jednostka może być dzieckiem w kilku relacjach rodzic / dziecko z różnymi typami rodziców. Kontynuując przykład Behranga, wyobraź sobie, że zadanie może być dzieckiem projektu, osoby, działu, badania i procesu.Czy
task
tabela powinna mieć 5nullable
pól kluczy obcych? Myślę, że nie...źródło
Jest to jedyne rozwiązanie umożliwiające mapowanie asocjacji ManyToMany: do mapowania powiązania potrzebna jest tabela łączenia między dwiema tabelami encji.
Jest również używany do asocjacji OneToMany (zwykle jednokierunkowych), gdy nie chcesz dodawać klucza obcego w tabeli wielu stron, a tym samym utrzymywać go niezależnie od jednej strony.
Wyszukaj @JoinTable w dokumentacji hibernacji, aby znaleźć wyjaśnienia i przykłady.
źródło
To pozwala ci radzić sobie w relacjach Wiele do wielu. Przykład:
Join Table umożliwia tworzenie mapowań przy użyciu:
utworzy tabelę:
źródło
@ManyToMany
wspomnieniaNajczęściej będziesz musiał użyć
@JoinTable
adnotacji, aby określić mapowanie relacji wiele do wielu tabel:Więc zakładając, że masz następujące tabele bazy danych:
W
Post
encji można zmapować tę relację w następujący sposób:@JoinTable
Adnotacja jest używana do określenia nazwy tabel za pomocąname
atrybutu, a także kolumny klucza obcego która odwołuje się dopost
tabeli (na przykładjoinColumns
), a kolumna klucz obcy wpost_tag
tabeli połączeń, która odwołuje sięTag
podmiot za pośrednictweminverseJoinColumns
atrybutu.@OneToMany
Asocjacje jednokierunkowe@OneToMany
Skojarzenia jednokierunkowe , którym brakuje@JoinColumn
odwzorowania, zachowują się jak relacje między tabelami wiele do wielu, a nie jeden do wielu.Więc zakładając, że masz następujące mapowania encji:
Hibernate przyjmie następujący schemat bazy danych dla powyższego mapowania encji:
Jak już wyjaśniono, jednokierunkowe
@OneToMany
mapowanie JPA zachowuje się jak asocjacja wiele do wielu.Aby dostosować tabelę linków, możesz również użyć
@JoinTable
adnotacji:A teraz zostanie wywołana tabela linków,
post_comment_ref
a kolumny klucza obcego będąpost_id
dlapost
tabeli ipost_comment_id
dlapost_comment
tabeli.źródło