Ho i prossimi due entità con una relazione OnetoOne tra di loro:Persist OnetoOne relazione con SpringData APP
@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 */
}
Sto cercando di eseguire questo codice:
Task task = taskService.findDispatchableTask();
if (task != null) {
Tracker tracker = trackerService.findIdleTracker();
if (tracker != null) {
task.setTracker(tracker);
task.setStatus(TaskStatus.DISPATCHED);
taskService.save(task);
}
}
Ma ottengo questo errore :
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
posso "risolvere" è cambiare il mio codice per:
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);
}
}
La mia domanda è: quale è il modo corretto per mantenere una relazione OneToOne? Nel mio codice, perché ho salvato entrambe le parti della relazione per farlo funzionare?
Grazie per la tua ottima risposta. Lo capisco adesso ma non capisco perché non devo salvare le mie entità in modo esplicito. Ciò che save() fa è chiamare il metodo save() del repository che è transazionale. Cosa dovrei fare? –
Il punto di una transazione deve essere in grado di cambiare più entità, di più tipi, atomicamente. O tutto è salvato, o niente è. Questo è ciò che garantisce la coerenza dei dati. Ed è per questo che i servizi dovrebbero essere transazionali e non solo i repository. Una volta caricate le entità in una transazione e modificate nella stessa transazione, Hibernate persiste automaticamente le modifiche, senza la necessità di salvarle esplicitamente. In breve, tutto il codice nella tua domanda dovrebbe essere in un metodo di servizio transazionale e non dovresti chiamare 'save()'. –