与 SpringData JPA 保持一对一关系 [英] Persist OneToOne relation with SpringData JPA

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

问题描述

我有接下来的两个实体,它们之间存在一对一关系:

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

但我收到此错误:

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?

推荐答案

我们又来了.

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

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.

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

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