Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

JPA menyisipkan hasil induk/anak di MySQLIntegrityConstraintViolationException

Hubungan Anda tidak harus dua arah. Ada beberapa informasi yang salah dalam komentar di sini.

Anda juga mengatakan bahwa Anda telah menambahkan bidang "parentId" ke dalam entitas Anak karena Anda berasumsi bahwa JPA perlu "tahu" tentang bidang induk agar dapat menetapkan nilainya. Masalahnya bukan JPA tidak tahu tentang lapangan, berdasarkan anotasi yang Anda berikan. Masalahnya adalah Anda telah memberikan "terlalu banyak" informasi tentang bidang tersebut, tetapi informasi tersebut tidak konsisten secara internal.

Ubah bidang dan anotasi Anda di Induk menjadi:

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
@JoinColumn(name = "parent_id")
private List<Child> children;

Kemudian hapus "parentId" dari entitas Anak seluruhnya. Anda sebelumnya telah menentukan anotasi JoinTable. Namun, yang Anda inginkan bukanlah JoinTable. JoinTable akan membuat tabel ketiga tambahan untuk menghubungkan dua entitas satu sama lain. Yang Anda inginkan hanyalah JoinColumn. Setelah Anda menambahkan anotasi JoinColumn ke bidang yang juga dianotasi dengan OneToMany, implementasi JPA Anda akan mengetahui bahwa Anda menambahkan FK ke tabel CHILD. Masalahnya adalah JPA memiliki tabel CHILD yang sudah ditentukan dengan kolom parent_id.

Anggap saja Anda memberikan dua definisi yang saling bertentangan dari fungsi tabel CHILD dan kolom parent_id. Dalam satu kasus, Anda telah memberi tahu Anda JPA bahwa itu adalah entitas dan parent_id hanyalah nilai dalam entitas itu. Di sisi lain, Anda telah memberi tahu JPA bahwa tabel CHILD Anda bukan entitas, tetapi digunakan untuk membuat hubungan kunci asing antara tabel CHILD dan PARENT Anda. Masalahnya adalah tabel CHILD Anda sudah ada. Kemudian ketika Anda mempertahankan entitas Anda, Anda telah memberi tahu bahwa parent_id secara eksplisit null (tidak disetel) tetapi kemudian Anda juga telah memberi tahu bahwa parent_id Anda harus diperbarui untuk menyetel referensi kunci asing ke tabel induk.

Saya memodifikasi kode Anda dengan perubahan yang saya jelaskan di atas, dan saya juga menyebut "bertahan" alih-alih "menggabungkan".

Ini menghasilkan 3 kueri SQL

insert into PARENT (ID) values (default)
insert into CHILD (ID) values (default)
update CHILD set parent_id=? where ID=?

Ini mencerminkan apa yang Anda inginkan dengan sempurna. Entri PARENT dibuat. Entri CHILD dibuat, dan kemudian record CHILD diperbarui untuk menyetel kunci asing dengan benar.

Jika Anda menambahkan anotasi

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
@JoinColumn(name = "parent_id", nullable = false)
private List<Child> children;

Kemudian akan menjalankan kueri berikut saat memasukkan anak

insert into CHILD (ID, parent_id) values (default, ?)

jadi atur FK Anda dengan benar sejak awal.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Baca file teks besar dan simpan setiap baris dalam database

  2. Bagaimana cara menggunakan bidang alfanumerik dengan klausa BETWEEN di Mysql?

  3. Pemecahan Masalah:Kesalahan MySQL/MariaDB #1044 Е Akses Ditolak untuk Pengguna

  4. Pemicu MySQL dimasukkan ke tabel lain

  5. Persistent vs non-Persistent - Mana yang harus saya gunakan?