Връзката ви не трябва да бъде двупосочна. В коментарите тук има някаква грешна информация.
Вие също казахте, че сте добавили полето "parentId" в обекта Child, защото сте приели, че JPA трябва да "знае" за родителското поле, за да може да зададе стойността. Проблемът не е, че JPA не знае за полето въз основа на анотациите, които сте предоставили. Проблемът е, че сте предоставили „твърде много“ информация за полето, но тази информация не е вътрешно последователна.
Променете полето и анотацията си в Родител на:
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
@JoinColumn(name = "parent_id")
private List<Child> children;
След това премахнете изцяло "parentId" от обекта Child. Преди това сте посочили анотация JoinTable. Това, което искате обаче, не е JoinTable. JoinTable ще създаде допълнителна трета таблица, за да свърже двата обекта един с друг. Това, което искате, е само JoinColumn. След като добавите анотацията JoinColumn към поле, което също е анотирано с OneToMany, вашата JPA реализация ще знае, че добавяте FK в таблицата CHILD. Проблемът е, че JPA има CHILD таблица, която вече е дефинирана с колона parent_id.
Помислете за това, че му давате две противоречиви дефиниции както на функцията на таблицата CHILD, така и на колоната parent_id. В един случай сте ви казали на JPA, че това е обект и parent_id е просто стойност в този обект. В другия, вие сте казали на JPA, че вашата CHILD таблица не е обект, а се използва за създаване на връзка с външен ключ между вашата CHILD и PARENT таблица. Проблемът е, че вашата CHILD таблица вече съществува. След това, когато запазвате обекта си, вие му казахте, че parent_id е изрично нулев (не е зададен), но след това също му казахте, че вашият parent_id трябва да бъде актуализиран, за да зададе препратка към външен ключ към родителската таблица.
Промених вашия код с промените, които описах по-горе, и също така нарекох „постоянство“ вместо „сливане“.
Това доведе до 3 SQL заявки
insert into PARENT (ID) values (default)
insert into CHILD (ID) values (default)
update CHILD set parent_id=? where ID=?
Това отразява идеално това, което искате. Записът РОДИТЕЛ е създаден. Записът CHILD се създава и след това записът CHILD се актуализира, за да зададе правилно външния ключ.
Ако вместо това добавите пояснението
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
@JoinColumn(name = "parent_id", nullable = false)
private List<Child> children;
След това ще изпълни следната заявка, когато вмъкне детето
insert into CHILD (ID, parent_id) values (default, ?)
по този начин настройвате правилно своя FK от самото начало.