beeinflussen habe ich eine Beziehung zwischen Eltern (Eigenschaften) und Kinder (Credit), meine Hibernate Konfiguration funktioniert für mich so lange in Ordnung Ich versuche, don `t um ein neues Child (Guthaben) durch Cascade über das Parent (Property) zu speichern.JPA/Hibernate @OneToMany optional mit Kind auf JoinTable - Speichern Eltern mehrere Einsätze auf JoinTable
Hibernate-Konfigurationen:
@Entity
public class Property implements Ownable {
...
@Valid
// ALSO TRIED WITH CascadeType.ALL !!!
@OneToMany(fetch = LAZY, cascade = {PERSIST, MERGE, REMOVE}, orphanRemoval = true)
@JoinTable(
name = "PROPERTY_CREDIT_OPTIONS",
joinColumns = @JoinColumn(name="PROPERTY_ID", nullable = false),
inverseJoinColumns = @JoinColumn(name = "CREDIT_ID", nullable = false, unique = true)
)
List<NotActiveCredit> creditOptions = new ArrayList<>();
...
}
@Entity
public class NotActiveCredit extends Credit {
@ManyToOne
@JoinTable(
name = "PROPERTY_CREDIT_OPTIONS",
inverseJoinColumns = @JoinColumn(name="PROPERTY_ID", nullable = false),
joinColumns = @JoinColumn(name = "CREDIT_ID", nullable = false, unique = true)
)
@NotNull @NonNull
Property property;
}
Controller-Call:
@PostMapping("/save")
public String save (
@ModelAttribute("property") @Valid Property formProperty,
BindingResult errors,
ModelMap modelMap
) {
if (!errors.hasErrors()) {
// formProperty has new Credit in the creditOptions List
// SAVE ONLY DELEGATS TO SPRING DATA REPOSITORY ...
final Property savedProperty = propertyService.save(formProperty);
...
} else {
// BLABLA
}
}
Die Protokollierung wie folgt aussieht:
Enter InvestmentController.save(...)
Enter PropertyServiceImpl.save(...)
insert into not_active_credit (id, interest_rate_nominal_in_percent, name_of_institution, redemption_at_begin_in_percent, special_redemption_each_year_in_percent) values (default, ?, ?, ?, ?)
binding parameter [1] as [NUMERIC] - [null]
binding parameter [2] as [VARCHAR] - [test]
binding parameter [3] as [NUMERIC] - [null]
binding parameter [4] as [NUMERIC] - [null]
insert into property_credit_options (property_id, credit_id) values (?, ?)
binding parameter [1] as [BIGINT] - [1]
binding parameter [2] as [BIGINT] - [1]
Exit PropertyServiceImpl.save Returns Property
// THEN WHEN IT CLOSE THE TRANSACTION IT WANTS TO INSERT JOIN TABLE AGAIN!
insert into property_credit_options (property_id, credit_id) values (?, ?)
binding parameter [1] as [BIGINT] - [1]
binding parameter [2] as [BIGINT] - [1]
SQL Error: -104, SQLState: 23505
integrity constraint violation: unique constraint or index violation; SYS_PK_10222 table: PROPERTY_CREDIT_OPTIONS
Mein Object`s Inhalt Alle Hinweise sind sehr willkommen.
Bearbeiten: Zusätzliche Informationen. Nach dem Aufruf des Repository. Speichern Sie die Liste wird immer noch als schmutzig (schmutzig = wahr). Sollte es nicht falsch sein, wenn es gerade gespeichert wurde, weil ich es in der Konsole sehen kann, senden Sie einfach SQL an db, indem Sie eine Einfügung machen. Beim Debuggen, wenn ich der Liste das dirty = false gebe, wird das Einfügen zum zweiten Mal nicht mehr ausgelöst und alles ist in Ordnung. Warum wird es nicht auf false gesetzt, nachdem Einfügungen an die DB gesendet wurden? Es sollte nicht mehr schmutzig sein, oder denke ich falsch?
SOLUTION
Als crizzis schlug ich @JoinTable
aus der Sammlung Eigenschaft creditOptions
in Klasse Property
entfernt und mappedBy='property'
hinzugefügt. Die Sammlung ist jetzt von übergeordneten Elementen aktualisierbar.
@Valid
@OneToMany(mappedBy="property", fetch = LAZY, cascade = ALL, orphanRemoval = true)
Collection<NotActiveCredit> creditOptions = new ArrayList<>();
Auf der anderen Seite auf Klasse NotActiveCredit
es ist wie folgt:
@ManyToOne
@JoinTable(
name = "PROPERTY_CREDIT_OPTIONS",
inverseJoinColumns = @JoinColumn(name="PROPERTY_ID", nullable = false),
joinColumns = @JoinColumn(name = "CREDIT_ID", nullable = false, unique = true)
)
@NotNull
Property property;
Hey, toll, ich habe gerade JoinTable aus der 'NotActiveCredit' Klasse entfernt und es funktioniert schon. 'mappedBy' war nicht notwendig. –
Dies wird weiterhin als separate Zuordnung behandelt. Der einzige Unterschied ist, dass '@ ManyToOne' standardmäßig eine Join-Spalte verwendet, so dass Sie wahrscheinlich eine zusätzliche' PROPERTY_ID'-Spalte in der 'NONACTIVECREDIT'-Tabelle sehen werden. Außerdem werden 'Property.creditOptions' und' NotActiveCredit.property' von JPA * nicht ** synchron gehalten. – crizzis
Die Tabelle 'not_active_credit' hat nur eine' property_id' erstellt, aber ich werde die Synchronisation genauer betrachten . Übrigens. Die Annotation @ManyToOne hat kein 'mappedBy', wo würden Sie vorschlagen, es hinzuzufügen? Vielen Dank. –