Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

JPA chèn kết quả cha / con trong MySQLIntegrityConstraintViolationException

Mối quan hệ của bạn không nhất thiết phải có tính chất hai chiều. Có một số thông tin sai trong các nhận xét ở đây.

Bạn cũng cho biết rằng bạn đã thêm trường "parentId" vào thực thể Con vì bạn cho rằng JPA cần "biết" về trường mẹ để nó có thể đặt giá trị. Vấn đề không phải là JPA không biết về lĩnh vực này, dựa trên các chú thích mà bạn đã cung cấp. Vấn đề là bạn đã cung cấp "quá nhiều" thông tin về lĩnh vực này, nhưng thông tin đó không nhất quán trong nội bộ.

Thay đổi trường và chú thích của bạn trong Gốc thành:

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

Sau đó, xóa hoàn toàn "parentId" khỏi thực thể Con. Trước đó bạn đã chỉ định chú thích JoinTable. Tuy nhiên, thứ bạn muốn không phải là JoinTable. Một JoinTable sẽ tạo thêm một bảng thứ ba để liên kết hai thực thể với nhau. Những gì bạn muốn chỉ là một JoinColumn. Khi bạn thêm chú thích JoinColumn vào một trường cũng được chú thích với OneToMany, việc triển khai JPA của bạn sẽ biết rằng bạn đang thêm FK vào bảng CHILD. Vấn đề là JPA có một bảng CHILD đã được xác định với một cột parent_id.

Hãy nghĩ rằng bạn đang đưa cho nó hai định nghĩa mâu thuẫn nhau về cả chức năng của bảng CHILD và cột parent_id. Trong một trường hợp, bạn đã nói với JPA rằng nó là một thực thể và parent_id chỉ đơn giản là một giá trị trong thực thể đó. Mặt khác, bạn đã nói với JPA rằng bảng CON của bạn không phải là một thực thể, nhưng được sử dụng để tạo mối quan hệ khóa ngoài giữa bảng CON và PHỤ HUYNH của bạn. Vấn đề là bảng CHILD của bạn đã tồn tại. Sau đó, khi bạn đang duy trì thực thể của mình, bạn đã nói với nó rằng parent_id rõ ràng là null (not set) nhưng sau đó bạn cũng đã nói với nó rằng parent_id của bạn nên được cập nhật để đặt tham chiếu khóa ngoại cho bảng mẹ.

Tôi đã sửa đổi mã của bạn với những thay đổi mà tôi đã mô tả ở trên và tôi cũng gọi là "dai dẳng" thay vì "hợp nhất".

Điều này dẫn đến 3 truy vấn SQL

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

Điều này phản ánh những gì bạn muốn một cách hoàn hảo. Mục nhập PARENT được tạo. Mục nhập CHILD được tạo và sau đó bản ghi CHILD được cập nhật để đặt khóa ngoại một cách chính xác.

Nếu thay vào đó bạn thêm chú thích

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

Sau đó, nó sẽ chạy truy vấn sau khi chèn con

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

do đó thiết lập FK của bạn đúng cách ngay từ đầu.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Microsoft SQL Server tương đương với MySQL REGEXP

  2. Cách tạo tập lệnh đăng nhập an toàn trong PHP và MySQL

  3. Ví dụ về CURRENT_TIMESTAMP - MySQL

  4. Tìm kiếm MySQL và thay thế một số văn bản trong một trường

  5. Thêm dấu ngắt dòng trong MySQL INSERT INTO văn bản