In Ordnung, ich bin ein wenig depreate jetzt. Ich habe viele der anderen verwandten Fragen gelesen, aber das hat mir noch nicht geholfen, mein Problem zu lösen. Ich bin froh, wenn mir jemand helfen kann.Richtig kaskadieren diese @ OneToMany-Beziehung (Spring Data JPA)
Ich verwende Spring Data JPA, und ich habe diese beiden Entitäten:
Device.class
private String id;
@OneToMany(mappedBy = "device", cascade = CascadeType.ALL)
@JsonIgnore
@RestResource(exported = false)
private List<Reading> readings;
Reading.class
@ManyToOne(cascade = {CascadeType.MERGE}) /*This isn't right...*/
@JoinColumn(name = "device_id")
private Device device;
Erwartung
ich nur Lesungen und erwarten, dass die Geräte werden richtig kaskadiert (beharrte oder fusionierten) bin zu speichern, je nachdem, ob es bereits vorhanden ist. (Die Messwerte werden nur einmal eingesetzt, sie werden nie aktualisiert)
Reality
ich nur diese Arbeit machen kann teilweise:
Wenn ich cascade = CascadeType.ALL
oder cascade = CascadeType.PERSIST
verwenden kann ich die erste speichern Lesen und zugeordnetes Gerät Sobald ich eine zweite Lesung einzufügen, das eine Beziehung zu dem gleichen Gerät hat, bekomme ich etwas entlang der Linien von:
Duplicate entry '457129' for key 'PRIMARY'
('457129' = Reading.Device.id)
Wie ich verstehe, versuchen die zweite Lese Unternehmen seine Geräte kaskadieren, indem eine neue Zeile einzufügen statt Aktualisierung der bestehenden.
Ich kann "umgehen" dies mit cascade = CascadeType.MERGE
stattdessen. Jetzt wird das Gerät korrekt aktualisiert, wenn ich eine neue Lesung mit einer vorhandenen Geräteentität speichere. ABER jetzt kann ich kein Gerät mehr kaskadieren, das noch nicht existiert!
Column 'device_id' cannot be null
(Reading.device_id)
Das Speichern
I erhalten JSON DTO und die Entitäten daraus erstellen.
Pseudocode:
Reading reading = deserialize(jsonReading);
Device device = deserialize(device);
reading.setDevice(device); /* Device entity is detached */
readingService.save(reading);
Ich denke, ein Teil des Problems bei mir vielleicht zu tun haben, eine freistehende Einheit einstellen?
Was mache ich falsch? Sind meine Beziehungen schlecht? Was ist los? Muss ich diese Transaktionen manuell verwalten?
Vielen Dank!
Ich entfernte die "Kaskade", aber das half nicht. Immer noch "Spalte" device_id "kann nicht null sein". Ich fügte der Frage auch den sparenden Teil hinzu, da es wichtig sein könnte. – sldk
Haben Sie Primärschlüssel mit '@ Id' Annotation definiert? Wenn Sie neue Objekte erstellen, lassen Sie die ID-Werte unverändert und verwenden Sie sie beim Aktualisieren (aber rufen Sie 'saveOrUpdate' in der Dao-Implementierung anstelle von' save' auf) –
Ja. '' @Id @GeneratedValue private int id; '' 'Reading''. '' @Id private String-ID; '' '' Device''. – sldk