Ada Kelas Entitas "A". Kelas A mungkin memiliki anak dengan tipe "A" yang sama. Juga "A" harus mengandung induknya jika itu adalah anak.
Apakah ini mungkin? Jika demikian, bagaimana cara memetakan relasi di kelas Entitas? ["A" memiliki kolom id.]
Ya, ini mungkin. Ini adalah kasus khusus dari standar dua arah @ManyToOne
/ @OneToMany
hubungan. Itu istimewa karena entitas di setiap ujung hubungan adalah sama. Kasus umum dirincikan dalam Bagian 2.10.2 dari spesifikasi JPA 2.0 .
Inilah contoh yang berhasil. Pertama, kelas entitas A
:
@Entity
public class A implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@ManyToOne
private A parent;
@OneToMany(mappedBy="parent")
private Collection<A> children;
// Getters, Setters, serialVersionUID, etc...
}
Berikut adalah main()
metode kasar yang mempertahankan tiga entitas tersebut:
public static void main(String[] args) {
EntityManager em = ... // from EntityManagerFactory, injection, etc.
em.getTransaction().begin();
A parent = new A();
A son = new A();
A daughter = new A();
son.setParent(parent);
daughter.setParent(parent);
parent.setChildren(Arrays.asList(son, daughter));
em.persist(parent);
em.persist(son);
em.persist(daughter);
em.getTransaction().commit();
}
Dalam kasus ini, ketiga contoh entitas harus dipertahankan sebelum transaksi dilakukan. Jika saya gagal mempertahankan salah satu entitas dalam grafik hubungan induk-anak, maka pengecualian akan diterapkan commit()
. Di Eclipselink, ini adalah RollbackException
detail ketidakkonsistenan.
Perilaku ini dapat dikonfigurasi melalui cascade
atribut pada A
's @OneToMany
dan @ManyToOne
penjelasan. Misalnya, jika saya menyetel cascade=CascadeType.ALL
kedua anotasi tersebut, saya dapat dengan aman mempertahankan salah satu entitas dan mengabaikan yang lainnya. Katakanlah saya bertahan parent
dalam transaksi saya. Pelaksanaan traverse JPA parent
's children
properti karena ditandai dengan CascadeType.ALL
. Implementasi JPA menemukan son
dan di daughter
sana. Itu kemudian berlanjut pada kedua anak atas nama saya, meskipun saya tidak secara eksplisit memintanya.
Satu catatan lagi. Itu selalu menjadi tanggung jawab programmer untuk memperbarui kedua sisi hubungan dua arah. Dengan kata lain, setiap kali saya menambahkan anak ke beberapa orang tua, saya harus memperbarui properti induk anak tersebut. Memperbarui hanya satu sisi hubungan dua arah adalah kesalahan menurut JPA. Selalu perbarui kedua sisi hubungan. Ini ditulis dengan jelas pada halaman 42 dari spesifikasi JPA 2.0:
Perhatikan bahwa aplikasilah yang memikul tanggung jawab untuk menjaga konsistensi hubungan waktu proses — misalnya, untuk memastikan bahwa sisi "satu" dan "banyak" dari hubungan dua arah konsisten satu sama lain ketika aplikasi memperbarui hubungan pada waktu proses .
Bagi saya triknya adalah menggunakan hubungan banyak-ke-banyak. Misalkan entitas A Anda adalah divisi yang dapat memiliki sub-divisi. Kemudian (melewatkan detail yang tidak relevan):
Karena saya memiliki logika bisnis yang luas di sekitar struktur hierarki dan JPA (berdasarkan model relasional) sangat lemah untuk mendukungnya, saya memperkenalkan antarmuka
IHierarchyElement
dan pendengar entitasHierarchyListener
:sumber
Top
adalah hubungan. Halaman 93 dari spesifikasi JPA 2.0, Entity Listeners dan Metode Callback: "Secara umum, metode siklus hidup aplikasi portabel tidak boleh menjalankan operasi EntityManager atau Query, mengakses instance entitas lain, atau mengubah hubungan". Baik? Beri tahu saya jika saya tidak aktif.