这是官方休眠教程的摘录
首先,请记住,冬眠不影响正常Java 语义。我们是如何在一个人和活动之间建立链接的 单向示例?您将事件的实例添加到 事件参考的收集,一个人的实例。如果你想 要使此链接双向,您必须对另一个链接进行同样的操作 通过在事件中添加一个人参考该集合的参考。这个 "在双方设置链接"的过程是绝对必要的 带有双向链接。
许多开发人员防御计划并创建链接管理方法 正确设置双方(例如,亲自设置):
protected Set getEvents() {
return events;
}
protected void setEvents(Set events) {
this.events = events;
}
public void addToEvent(Event event) {
this.getEvents().add(event);
event.getParticipants().add(this);
}
public void removeFromEvent(Event event) {
this.getEvents().remove(event);
event.getParticipants().remove(this);
}
在这种情况下,"绝对"这个词是什么意思?:
- 指的是,只要当前的逻辑过程完成,建议保持关系一致,但显然可以发生持久性?
- 意味着如果不设置对方(不拥有关系),持久性 strictly >不进行?
换句话说,如果我的"添加"方法是:
public void addToEvent(Event event) {
this.getEvents().add(event);
//event.getParticipants().add(this); without this line
}
bi-directional
关系允许两个实体参与关系,以获取关系另一侧的实体。当您插入参与双向关系的这些实体时,您将负责管理关系的双方。
在参与者/事件关系中,您提出了这是通过在关系两边设置适当的实体来完成的。
因此,如果您尝试为参与者添加事件,则必须将活动添加到参与者Collection<Event>
中,并且必须将参与者添加到活动的Collection<Participant>
中。您不能简单地将事件添加到参与者的Collection<Event>
,并期望Hibernate在事件的Collection<Participant>
中填充Participant
。
如果您未能将Participant
添加到Collection<Participant>
的事件中,则Collection<Participant>
将与数据库不同步,并且可能无法根据已建立的约束和级联设置插入。
正如其他答案所指出的那样,冬眠不会打破正常的Java语义。将参与者添加到活动中的集合中不会透明地将活动添加到参与者的集合中。您负责设置它。
根据文档(不是教程):
仅在关联的反端进行的更改不持续。 ... 非内部侧用于将内存表示形式保存到数据库中。
在这是直接从文档Item
的代码示例是协会的反面:
category.getItems().add(item); // The category now "knows" about the relationship
item.getCategories().add(category); // The item now "knows" about the relationship
session.persist(item); // The relationship won't be saved!
session.persist(category); // The relationship will be saved
总而言之,从我对文档的阅读中,这不是绝对必要的,但未能将反向侧实体添加到非偏移侧的集合中,将导致关系不保存。
这意味着当您添加关系的一侧时,两个数据结构的内存副本都不会自动更新,因此当您的代码使用Java Proxies时,行,您可能会将事件添加到参与者的事件列表中,但是该事件不会显示参与者,并且(合理地)依靠两个人同步的任何代码都会失败。这是JPA中令人讨厌的陷阱,但这不是冬眠特定的,并且似乎不会很快消失。