sql >> Database teknologi >  >> RDS >> Mysql

JPA indsæt forældre/barn resultater i MySQLIintegrityConstraintViolationException

Dit forhold behøver ikke at være tovejs. Der er nogle forkerte oplysninger i kommentarerne her.

Du sagde også, at du havde tilføjet feltet "parentId" i Child-enheden, fordi du antog, at JPA skal "kende" til det overordnede felt, så det kan indstille værdien. Problemet er ikke, at JPA ikke kender til feltet, baseret på de anmærkninger, du har givet. Problemet er, at du har givet "for meget" information om feltet, men den information er ikke internt konsistent.

Skift dit felt og annotation i Overordnet til:

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

Fjern derefter "parentId" fra Child-enheden helt. Du havde tidligere angivet en JoinTable-annotering. Men det, du ønsker, er ikke en JoinTable. En JoinTable ville skabe en ekstra tredje tabel for at relatere de to enheder til hinanden. Det, du ønsker, er kun en JoinColumn. Når du tilføjer JoinColumn-annotationen til et felt, der også er kommenteret med OneToMany, vil din JPA-implementering vide, at du tilføjer en FK i CHILD-tabellen. Problemet er, at JPA allerede har en CHILD-tabel defineret med en kolonne parent_id.

Tænk på, at du giver den to modstridende definitioner af både funktionen af ​​CHILD-tabellen og kolonnen parent_id. I et tilfælde har du fortalt dig JPA, at det er en enhed, og parent_id er simpelthen en værdi i denne enhed. I den anden har du fortalt JPA, at din CHILD-tabel ikke er en entitet, men bruges til at skabe et fremmednøgleforhold mellem din CHILD- og PARENT-tabel. Problemet er, at din CHILD-tabel allerede eksisterer. Når du så fortsætter din enhed, har du fortalt den, at parent_id'et eksplicit er null (ikke sat), men så har du også fortalt det, at dit parent_id skal opdateres for at sætte en fremmednøglereference til den overordnede tabel.

Jeg ændrede din kode med de ændringer, jeg beskrev ovenfor, og jeg kaldte også "vedvarende" i stedet for "flet".

Dette resulterede i 3 SQL-forespørgsler

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

Dette afspejler perfekt, hvad du ønsker. Forældreposten oprettes. CHILD-posten oprettes, og derefter opdateres CHILD-posten for at indstille fremmednøglen korrekt.

Hvis du i stedet tilføjer annotationen

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

Så vil den køre følgende forespørgsel, når den indsætter barnet

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

dermed indstille din FK korrekt fra begyndelsen.



  1. Kan ikke indlæse godkendelsesplugin 'caching_sha2_password'

  2. Hvordan kan jeg bruge SQL's YEAR(), MONTH() og DAY() i Doctrine2?

  3. Sådan ændres Change Data Capture (CDC) opbevaringsperiode i SQL Server - SQL Server-vejledning

  4. JDBC - Statement, PreparedStatement, CallableStatement og caching