Dalam hal apa Anda menggunakan @JoinTableanotasi JPA ?
Dalam hal apa Anda menggunakan @JoinTableanotasi JPA ?
Jawaban:
EDIT 2017-04-29 : Seperti yang ditunjukkan oleh beberapa komentator, JoinTablecontohnya tidak memerlukan mappedByatribut anotasi. Bahkan, versi terbaru dari Hibernate menolak untuk memulai dengan mencetak kesalahan berikut:
org.hibernate.AnnotationException:
Associations marked as mappedBy must not define database mappings
like @JoinTable or @JoinColumn
Mari kita berpura-pura bahwa Anda memiliki entitas bernama Projectdan entitas lain bernama Taskdan setiap proyek dapat memiliki banyak tugas.
Anda bisa mendesain skema database untuk skenario ini dengan dua cara.
Solusi pertama adalah membuat tabel bernama Projectdan tabel lain bernama Taskdan menambahkan kolom kunci asing ke tabel tugas bernama project_id:
Project Task
------- ----
id id
name name
project_id
Dengan cara ini, akan mungkin untuk menentukan proyek untuk setiap baris di tabel tugas. Jika Anda menggunakan pendekatan ini, di kelas entitas Anda, Anda tidak perlu tabel bergabung:
@Entity
public class Project {
@OneToMany(mappedBy = "project")
private Collection<Task> tasks;
}
@Entity
public class Task {
@ManyToOne
private Project project;
}
Solusi lain adalah dengan menggunakan tabel ketiga, misalnya Project_Tasks, dan menyimpan hubungan antara proyek dan tugas dalam tabel itu:
Project Task Project_Tasks
------- ---- -------------
id id project_id
name name task_id
The Project_Taskstabel disebut "Join Table". Untuk mengimplementasikan solusi kedua ini di JPA Anda perlu menggunakan@JoinTable anotasi. Misalnya, untuk menerapkan asosiasi satu-ke-satu yang uni-directional, kita dapat mendefinisikan entitas kita sebagai berikut:
Project kesatuan:
@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 kesatuan:
@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;
}
}
Ini akan membuat struktur database berikut:
The @JoinTablepenjelasan juga memungkinkan Anda menyesuaikan berbagai aspek tabel bergabung. Misalnya, sudahkah kami memberi anotasi pada tasksproperti seperti ini:
@JoinTable(
name = "MY_JT",
joinColumns = @JoinColumn(
name = "PROJ_ID",
referencedColumnName = "PID"
),
inverseJoinColumns = @JoinColumn(
name = "TASK_ID",
referencedColumnName = "TID"
)
)
@OneToMany
private List<Task> tasks;
Database yang dihasilkan akan menjadi:
Akhirnya, jika Anda ingin membuat skema untuk asosiasi banyak-ke-banyak, menggunakan tabel bergabung adalah satu-satunya solusi yang tersedia.
@JoinTable/@JoinColumndapat dijelaskan pada bidang yang sama dengan mappedBy. Jadi contoh yang benar harus menjaga mappedBydi Project, dan memindahkan @JoinColumnke Task.project (atau sebaliknya)
Project_Tasksmembutuhkan namedari Taskjuga, yang menjadi tiga kolom: project_id, task_id, task_name, bagaimana untuk mencapai hal ini?
Caused by: org.hibernate.AnnotationException: Associations marked as mappedBy must not define database mappings like @JoinTable or @JoinColumn:
Juga lebih bersih untuk digunakan @JoinTableketika Entitas dapat menjadi anak dalam beberapa hubungan orang tua / anak dengan berbagai jenis orang tua. Untuk menindaklanjuti dengan contoh Behrang, bayangkan Tugas dapat menjadi anak dari Proyek, Orang, Departemen, Studi, dan Proses.
Haruskah tasktabel memiliki 5 nullablebidang kunci asing? Saya pikir tidak...
Ini satu-satunya solusi untuk memetakan asosiasi ManyToMany: Anda memerlukan tabel gabungan antara tabel dua entitas untuk memetakan asosiasi.
Ini juga digunakan untuk asosiasi OneToMany (biasanya searah) ketika Anda tidak ingin menambahkan kunci asing di tabel banyak sisi dan dengan demikian tetap independen dari satu sisi.
Cari @JoinTable di dokumentasi hibernate untuk penjelasan dan contoh.
Ini memungkinkan Anda menangani hubungan Many to Many. Contoh:
Table 1: post
post has following columns
____________________
| ID | DATE |
|_________|_________|
| | |
|_________|_________|
Table 2: user
user has the following columns:
____________________
| ID |NAME |
|_________|_________|
| | |
|_________|_________|
Bergabung dengan Tabel memungkinkan Anda membuat pemetaan menggunakan:
@JoinTable(
name="USER_POST",
joinColumns=@JoinColumn(name="USER_ID", referencedColumnName="ID"),
inverseJoinColumns=@JoinColumn(name="POST_ID", referencedColumnName="ID"))
akan membuat tabel:
____________________
| USER_ID| POST_ID |
|_________|_________|
| | |
|_________|_________|
@ManyToMany asosiasiPaling sering, Anda harus menggunakan @JoinTableanotasi untuk menentukan pemetaan hubungan tabel banyak-ke-banyak:
Jadi, anggap Anda memiliki tabel database berikut:
Di Postentitas, Anda akan memetakan hubungan ini, seperti ini:
@ManyToMany(cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
@JoinTable(
name = "post_tag",
joinColumns = @JoinColumn(name = "post_id"),
inverseJoinColumns = @JoinColumn(name = "tag_id")
)
private List<Tag> tags = new ArrayList<>();
The @JoinTablepenjelasan digunakan untuk menentukan nama tabel melaluiname atribut, serta kolom Foreign Key yang referensi yang posttabel (misalnya, joinColumns) dan kolom Foreign Key di post_tagtabel link yang referensi yang Tagentitas melalui inverseJoinColumnsatribut.
Perhatikan bahwa atribut kaskade
@ManyToManyanotasi diatur kePERSISTdanMERGEhanya karenaREMOVEadalah ide yang buruk karena kita pernyataan DELETE akan dikeluarkan untuk catatan induk lainnya,tagdalam kasus kami, bukan kepost_tagcatatan. Untuk detail lebih lanjut tentang topik ini, lihat artikel ini .
@OneToManyAsosiasi searah@OneToManyAsosiasi searah , yang kurang a@JoinColumn pemetaan, berperilaku seperti hubungan tabel banyak-ke-banyak, bukan satu-ke-banyak.
Jadi, dengan asumsi Anda memiliki pemetaan entitas berikut:
@Entity(name = "Post")
@Table(name = "post")
public class Post {
@Id
@GeneratedValue
private Long id;
private String title;
@OneToMany(
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
//Constructors, getters and setters removed for brevity
}
@Entity(name = "PostComment")
@Table(name = "post_comment")
public class PostComment {
@Id
@GeneratedValue
private Long id;
private String review;
//Constructors, getters and setters removed for brevity
}
Hibernate akan mengasumsikan skema database berikut untuk pemetaan entitas di atas:
Seperti yang sudah dijelaskan, @OneToManypemetaan JPA searah berperilaku seperti asosiasi banyak-ke-banyak.
Untuk menyesuaikan tabel tautan, Anda juga dapat menggunakan @JoinTableanotasi:
@OneToMany(
cascade = CascadeType.ALL,
orphanRemoval = true
)
@JoinTable(
name = "post_comment_ref",
joinColumns = @JoinColumn(name = "post_id"),
inverseJoinColumns = @JoinColumn(name = "post_comment_id")
)
private List<PostComment> comments = new ArrayList<>();
Dan sekarang, tabel tautan akan dipanggil post_comment_refdan kolom Kunci Asing akan post_id, untuk posttabel, dan post_comment_id, untukpost_comment tabel.
@OneToManyAsosiasi searah tidak efisien, jadi Anda lebih baik menggunakan@OneToManyasosiasi dua arah atau hanya@ManyToOnesisi. Lihat artikel ini untuk detail lebih lanjut tentang topik ini.