Ich habe die nächsten zwei Entitäten mit einer OneToOne Beziehung zwischen ihnen:Persist OneToOne Beziehung mit SpringData JPA
@Entity
@Table(name = "tasks")
public class Task {
@OneToOne(mappedBy = "task", cascade = CascadeType.PERSIST)
private Tracker tracker;
/* More code */
}
@Entity
@Table(name = "trackers")
public class Tracker {
@OneToOne
@JoinColumn(name = "trk_task", unique = true)
private Task task;
/* More code */
}
Ich versuche, diesen Code auszuführen:
Task task = taskService.findDispatchableTask();
if (task != null) {
Tracker tracker = trackerService.findIdleTracker();
if (tracker != null) {
task.setTracker(tracker);
task.setStatus(TaskStatus.DISPATCHED);
taskService.save(task);
}
}
Aber ich habe diesen Fehler :
ERROR org.hibernate.AssertionFailure - an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
org.hibernate.AssertionFailure: non-transient entity has a null id
I "lösen" kann es meinen Code zu ändern:
Task task = taskService.findDispatchableTask();
if (task != null) {
Tracker tracker = trackerService.findIdleTracker();
if (tracker != null) {
tracker.setTask(task);
trackerService.save(tracker);
task.setTracker(tracker);
task.setStatus(TaskStatus.DISPATCHED);
taskService.save(task);
}
}
Meine Frage ist, Was ist der richtige Weg, um eine OneToOne-Beziehung zu bestehen? Warum muss ich in meinem Code beide Teile der Beziehung speichern, damit sie funktioniert?
Vielen Dank für Ihre großartige Antwort. Ich verstehe es jetzt, aber ich verstehe nicht, warum ich meine Entitäten nicht explizit speichern muss. Was save() tut, ist das Repository save() -Methode aufzurufen, das transaktional ist. Was soll ich machen? –
Der Punkt einer Transaktion besteht darin, mehrere Entitäten mehrerer Arten atomar ändern zu können. Entweder ist alles gerettet, oder nichts ist. Das garantiert die Kohärenz der Daten. Aus diesem Grund sollten die Services transaktional sein und nicht nur die Repositories. Sobald Sie Entitäten in einer Transaktion laden und sie in derselben Transaktion ändern, behält Hibernate die Änderungen automatisch bei, ohne sie explizit speichern zu müssen. Kurz gesagt, der gesamte Code in Ihrer Frage sollte in einer transaktionalen Service-Methode sein, und Sie sollten 'save()' nicht aufrufen müssen. –