Mysql
 sql >> Baza danych >  >> RDS >> Mysql

JPA wstawia wyniki nadrzędne/podrzędne w MySQLIntegrityConstraintViolationException

Twój związek nie musi być dwukierunkowy. W komentarzach znajdują się pewne nieprawdziwe informacje.

Powiedziałeś również, że dodałeś pole „parentId” do encji Child, ponieważ założyłeś, że JPA musi „wiedzieć” o polu nadrzędnym, aby móc ustawić wartość. Problem nie polega na tym, że JPA nie wie o tym polu na podstawie podanych przez Ciebie adnotacji. Problem polega na tym, że podałeś „zbyt dużo” informacji o polu, ale te informacje nie są wewnętrznie spójne.

Zmień swoje pole i adnotację w Rodzic na:

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

Następnie całkowicie usuń "parentId" z encji Child. Wcześniej określono adnotację JoinTable. Jednak to, czego chcesz, nie jest tabelą JointTable. JointTable stworzyłby dodatkową trzecią tabelę, aby powiązać ze sobą te dwie jednostki. To, czego chcesz, to tylko JoinColumn. Po dodaniu adnotacji JoinColumn do pola, które jest również opatrzone adnotacjami OneToMany, implementacja JPA będzie wiedziała, że ​​dodajesz FK do tabeli CHILD. Problem polega na tym, że JPA ma już zdefiniowaną tabelę CHILD z kolumną parent_id.

Pomyśl o tym, że dajesz mu dwie sprzeczne definicje zarówno funkcji tabeli CHILD, jak i kolumny parent_id. W jednym przypadku powiedziałeś JPA, że jest to encja, a parent_id to po prostu wartość w tej encji. W drugim, powiedziałeś JPA, że twoja tabela CHILD nie jest jednostką, ale jest używana do tworzenia relacji klucza obcego między twoją tabelą CHILD i PARENT. Problem polega na tym, że Twoja tabela CHILD już istnieje. Następnie, gdy utrwalasz swoją encję, powiedziałeś mu, że parent_id jest jawnie pusty (nieustawiony), ale powiedziałeś również, że twój parent_id powinien zostać zaktualizowany, aby ustawić odwołanie do klucza obcego do tabeli nadrzędnej.

Zmodyfikowałem Twój kod za pomocą zmian, które opisałem powyżej, a także nazwałem „utrwalić” zamiast „scal”.

Zaowocowało to 3 zapytaniami SQL

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

To doskonale odzwierciedla to, czego chcesz. Wpis PARENT jest tworzony. Wpis DZIECKO jest tworzony, a następnie rekord DZIECKO jest aktualizowany w celu prawidłowego ustawienia klucza obcego.

Jeśli zamiast tego dodasz adnotację

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

Następnie uruchomi następujące zapytanie po wstawieniu dziecka

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

w ten sposób odpowiednio ustawiając FK od samego początku.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL wybierz jedną kolumnę DISTINCT, z odpowiednimi innymi kolumnami

  2. PHP-MySQL-Jak bezpiecznie zwiększać pole integer MySQL?

  3. Jak korzystać z Coalesce w MySQL

  4. Jak wykonać zapytanie, które jest zapisane w kolumnie tabeli MySQL?

  5. INSERT INTO kończy się niepowodzeniem z node-mysql