sql >> Databasteknik >  >> RDS >> Mysql

JPA infoga förälder/underordnade resultat i MySQLIintegrityConstraintViolationException

Din relation behöver inte vara dubbelriktad. Det finns en del felaktig information i kommentarerna här.

Du sa också att du hade lagt till fältet "parentId" i Child-entiteten eftersom du antog att JPA behöver "veta" om det överordnade fältet så att det kan ställa in värdet. Problemet är inte att JPA inte känner till området, baserat på de anteckningar som du har tillhandahållit. Problemet är att du har tillhandahållit "för mycket" information om fältet, men den informationen är inte internt konsekvent.

Ändra ditt fält och anteckning i Parent till:

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

Ta sedan bort "parentId" från Child-entiteten helt och hållet. Du hade tidigare angett en JoinTable-anteckning. Men det du vill ha är inte ett JoinTable. En JoinTable skulle skapa ytterligare en tredje tabell för att relatera de två enheterna till varandra. Det du vill ha är bara en JoinColumn. När du har lagt till JoinColumn-kommentaren i ett fält som också är kommenterat med OneToMany, kommer din JPA-implementering att veta att du lägger till en FK i CHILD-tabellen. Problemet är att JPA har en CHILD-tabell redan definierad med en kolumn parent_id.

Tänk på att du ger den två motstridiga definitioner av både funktionen för tabellen CHILD och kolumnen parent_id. I ett fall har du sagt till JPA att det är en enhet och parent_id är helt enkelt ett värde i den entiteten. I den andra har du sagt till JPA att din CHILD-tabell inte är en enhet, utan används för att skapa en främmande nyckelrelation mellan din CHILD- och PARENT-tabell. Problemet är att ditt CHILD-bord redan finns. När du sedan behåller din entitet har du sagt till den att parent_id är uttryckligen null (inte satt) men sedan har du också sagt till den att ditt parent_id ska uppdateras för att ställa in en främmande nyckelreferens till den överordnade tabellen.

Jag modifierade din kod med ändringarna jag beskrev ovan, och jag kallade även "bestå" istället för "sammanfoga".

Detta resulterade i 3 SQL-frågor

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

Detta speglar vad du vill ha perfekt. Föräldraposten skapas. CHILD-posten skapas och sedan uppdateras CHILD-posten för att korrekt ställa in den främmande nyckeln.

Om du istället lägger till anteckningen

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

Sedan kör den följande fråga när den infogar barnet

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

ställ alltså in din FK rätt från början.



  1. java.sql.SQLException:Ingen databas har valts

  2. Hur hanterar man för många samtidiga anslutningar även efter att ha använt en anslutningspool?

  3. Hur hittar jag det vanligaste resultatet i en kolumn i min MySQL-tabell

  4. Hur man får gårdagens datum i MySQL