Persist OneToOne relation with SpringData JPA

孤人 提交于 2019-11-29 14:08:20

问题


I have the next two entities with a OneToOne relation between them:

@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 */
}

I'm trying to run this code:

Task task = taskService.findDispatchableTask();
if (task != null) {
    Tracker tracker = trackerService.findIdleTracker();
    if (tracker != null) {
        task.setTracker(tracker);
        task.setStatus(TaskStatus.DISPATCHED);
        taskService.save(task);
    }
}

But I get this error:

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 can "solve" it changing my code to:

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);
    }
}

My question is, Which is the proper way to persist a OneToOne relation? In my code, Why do I have save both parts of the relation to make it work?


回答1:


Here we go again.

Every bidirectional association has two sides : the owner side, and the inverse side. The inverse side is the one which has the mappedBy attribute. The owner side is the other one. JPA/Hibernate only cares about the owner side. So if you just initialize the inverse side, the association won't be persisted.

It's a good practice, generally, to initialize both sides of the association. First because it makes sure the owner side is initialized, and second because it makes the graph of entities coherent, for your own good.

Also note that if you're working inside a transaction (and you should), all the entities returned by your queries are attached entities. The changes applied to the entities are automatically made persistent when the transaction is committed (or before). There is no need to save the entities explicitely like you're doing.



来源:https://stackoverflow.com/questions/16380008/persist-onetoone-relation-with-springdata-jpa

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!