sql >> Database >  >> RDS >> Mysql

JPA voegt bovenliggende/onderliggende resultaten toe aan MySQLIntegrityConstraintViolationException

Je relatie hoeft niet tweerichtingsverkeer te zijn. Er is wat verkeerde informatie in de opmerkingen hier.

U zei ook dat u het veld "parentId" had toegevoegd aan de onderliggende entiteit, omdat u ervan uitging dat JPA het bovenliggende veld moet "weten" zodat het de waarde kan instellen. Het probleem is niet dat JPA het veld niet kent, op basis van de annotaties die u hebt verstrekt. Het probleem is dat je "te veel" informatie over het veld hebt verstrekt, maar die informatie is niet intern consistent.

Wijzig uw veld en annotatie in Parent in:

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

Verwijder vervolgens de "parentId" volledig uit de onderliggende entiteit. U had eerder een JoinTable-annotatie opgegeven. Wat u echter wilt, is geen JoinTable. Een JoinTable zou een extra derde tabel creëren om de twee entiteiten aan elkaar te relateren. Wat je wilt is alleen een JoinColumn. Zodra u de JoinColumn-annotatie toevoegt aan een veld dat ook is geannoteerd met OneToMany, weet uw JPA-implementatie dat u een FK toevoegt aan de CHILD-tabel. Het probleem is dat JPA een CHILD-tabel heeft die al is gedefinieerd met een kolom parent_id.

Bedenk dat je het twee tegenstrijdige definities geeft van zowel de functie van de CHILD-tabel als de parent_id-kolom. In één geval heb je JPA verteld dat het een entiteit is en de parent_id is gewoon een waarde in die entiteit. In de andere heb je JPA verteld dat je CHILD-tabel geen entiteit is, maar wordt gebruikt om een ​​refererende-sleutelrelatie te creëren tussen je CHILD- en PARENT-tabel. Het probleem is dat uw CHILD-tafel al bestaat. Wanneer u uw entiteit voortzet, hebt u hem verteld dat de parent_id expliciet null is (niet ingesteld), maar u hebt hem ook verteld dat uw parent_id moet worden bijgewerkt om een ​​refererende sleutelreferentie naar de bovenliggende tabel in te stellen.

Ik heb je code aangepast met de wijzigingen die ik hierboven heb beschreven, en ik heb ook 'persistent' genoemd in plaats van 'merge'.

Dit resulteerde in 3 SQL-query's

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

Dit geeft perfect weer wat je wilt. Het PARENT-item wordt gemaakt. Het KIND-item wordt gemaakt en vervolgens wordt het KIND-record bijgewerkt om de externe sleutel correct in te stellen.

Als u in plaats daarvan de annotatie toevoegt

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

Dan zal het de volgende query uitvoeren wanneer het het kind invoegt

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

dus je FK vanaf het begin goed instellen.



  1. Kortingscodesysteem maken (MySQL/php)

  2. MySQL:wanneer zijn Flush-privileges in MySQL echt nodig?

  3. Converteer JSON-array in MySQL naar rijen

  4. Is er een Oracle SQL-query die meerdere rijen in één rij samenvoegt?