3

如果在关系上使用 PERSIST 级联类型,在所有者侧或另一侧保存实体有什么区别?

@Entity
public class Slot {
    @OneToOne(mappedBy = "slot", cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
    private Cartridge cartridge;
}

@Entity
public class Cartridge {
    @OneToOne(cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
    private Slot slot;
}

问题:

slot.setCartridge(cartridge);
slot.save();

对比

cartridge.setSlot(slot)
cartridge.save();

slot.save() 或弹药筒.save() 似乎不一样...

两个实体都已保存。我只是想设置它们之间的关系。

4

3 回答 3

1

Cartridge 拥有该关系,这意味着必须为要在大多数提供程序中更新的外键设置 Cartridge.slot 值。JPA 规范还指出,您应该维护双向关系的双方,以使它们与数据库中的内容保持同步 - 因此,如果您的 setCartridge 也没有以某种方式设置关系的另一方,那么当您下次读取墨盒时,它可能没有设置插槽。JPA 取消了旧 EJB 规范中的关系维护,使实体的行为尽可能地像常规 Java 对象。

你应该调用类似的东西:

slot.setCartridge(cartridge);
cartridge.setSlot(slot)

然后保存在插槽或墨盒上 - 它不重要,因为合并将在任一方向级联到引用的对象。

于 2012-11-22T15:53:04.650 回答
1

是的,JPA 可能就像 Chris 所说的那样工作,也就是说,您应该通过同时设置双方来保持关系的最新状态。

但是,恕我直言,最好通过限制 API 来防止此问题。设置器应该只在关系所有者端实现。这样就没有办法从另一边更改值,无论如何都会被 ORM 忽略。

在您当前的示例中,这意味着 Cartridge 应该实现该setSlot()方法,而 Slot 不应该具有该setCartridge()方法。(不过,您可能做得更好,让 slot 成为所有者。)

于 2012-11-22T16:24:03.027 回答
0

在我看来,有一个区别。当您使用父对象保存实体时,它首先插入父实体,然后在保存子实体之前将生成的密钥分配给子实体。

当您先保存子实体时,它会不一样。

于 2012-11-22T14:36:26.680 回答