坚持OneToOne与SpringData JPA的关系 [英] Persist OneToOne relation with SpringData JPA

查看:149
本文介绍了坚持OneToOne与SpringData JPA的关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有下一个两个实体之间有OneToOne关系:

  @Entity 
@Table(name =任务)
公共类任务{
@OneToOne(mappedBy =task,cascade = CascadeType.PERSIST)
私人跟踪器跟踪器;

/ *更多代码* /
}

@Entity
@Table(name =trackers)
public class Tracker {
@OneToOne
@JoinColumn(name =trk_task,unique = true)
私人任务任务;

/ *更多代码* /
}

m试图运行这段代码:

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

但是我得到这个错误:

  ERROR org.hibernate.AssertionFailure  - 发生断言失败(这可能表示Hibernate中存在错误,但更可能是由于会话的不安全使用)
org.hibernate.AssertionFailure:非瞬时实体有一个空ID

我可以解决它将我的代码更改为:

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


$ / code>

我的问题是,持续存在的正确方法是什么OneToOne关系?在我的代码中,为什么我保存了关系的两个部分以使其工作?

解决方案

/ p>

每个双向关联都有两个方面:所有者方和反方。反面是具有 mappedBy 属性的那一面。所有者方是另一方。 JPA / Hibernate只关心所有者方面。所以如果你只是初始化反面,关联不会被持久化。

一般来说,初始化关联的双方是一种很好的做法。首先是因为它确保所有者方面已经初始化,其次是因为它使得图的实体连贯一致,为了您自己的利益。

另外请注意,如果你在工作在事务内部(你应该),查询返回的所有实体都是附属实体。当事务提交时(或之前),应用于实体的更改会自动保持不变。没有必要像你在做的那样明确地保存实体。


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?

解决方案

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.

这篇关于坚持OneToOne与SpringData JPA的关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆