双向OneToOne关系不对称保存?

时间:2012-11-22 14:26:59

标签: java jpa orm relation ebean

如果在关系中使用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();

VS

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

slot.save()或者cartridge.save()似乎不一样......

两个人都已经保存了。我只想设置它们之间的关系。

3 个答案:

答案 0 :(得分:1)

Cartridge拥有这种关系,这意味着必须为大多数提供商中更新的外键设置cartridge.slot值。 JPA规范还规定,您应该保持双向关系的双方以使它们与数据库中的内容保持同步 - 如果您的setCartridge没有以某种方式设置关系的另一面,那么当您下次阅读cartrige时,它可能没有插槽集。 JPA从旧的EJB规范中删除了关系maintanace,使得实体的行为尽可能地更像普通的java对象。

你应该打电话给:

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

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

答案 1 :(得分:1)

是的,JPA可能正如克里斯所说的那样工作,也就是说,你应该通过同时设置双方来保持关系的最新状态。

但是,恕我直言,最好通过限制API来防止此问题。 setter只能在关系所有者方面实现。这样就无法改变另一方的值,无论如何都会被ORM忽略。

在您当前的示例中,这意味着Cartridge应该实现setSlot()方法,而Slot不应该使用setCartridge()方法。 (尽管如此,你可能做得更好,让老板成为主人。)

答案 2 :(得分:0)

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

首先保存子实体时,它将不相同。