关系所有者在双向关系中意味着什么?

时间:2012-01-19 18:30:42

标签: hibernate

我有一个带有QuestionChoice对象的简单模型。

  • 一个问题有很多选择。
  • 许多选择有一个问题

使用Hibernate

有两种方法可以实现

实施一:业主方是选择

Question.java

@OneToMany (mappedBy="question")
private Set choices = new HashSet();

Choice.java

@ManyToOne
@JoinColumn (name="QUESTION_ID")
private Question question;

实施二:业主方是问题

Question.java

@OneToMany
@JoinColumn (name = "QUESTION_ID")
private Set choices = new HashSet();

Choice.java

@ManyToOne
@JoinColumn (name="QUESTION_ID", updatable = false, insertable = false)
private Question question;

两种实现有什么区别?

2 个答案:

答案 0 :(得分:16)

您的第一个示例是正常且正确的双向一对多/多对一映射。将Question设置为Choice - 属性("拥有方")足以保持关系。内存中的实体图将被混乱,直到再次从数据库中读取关系的另一侧。来自 数据库视点所有者是持久化到具有外键列的表的实体(对于双向一对一相同)。在说明书中,这将按以下方式解释:

  

一对多/多对一双向关系的多方面   必须是拥有方,因此mappedBy元素不能   在ManyToOne注释上指定   ....
  双向   托管实体之间的关系将基于持久化   由关系的拥有方持有的参考文献。它是   开发人员有责任保持内存中的引用   拥有方与反方保持一致   当他们改变时彼此相对。在单向一对一的情况下   和一对多的关系,是开发人员的责任   确保遵守关系的语义。

在JPA术语中,由于缺少mappedBy,您的第二个示例没有拥有方。相反,您有两个单向关系,强制使用相同的列作为存储。至少对于Hibernate 3.5.6,它将遵循以下方式:

  • Question设置为choice - 属性不会保持关系。
  • Choice添加到question - 属性不会保持关系。
  • 要将值保持为"QUESTION_ID"两者都必须设置(是的,也不是 - insertable question)。

答案 1 :(得分:0)

要记住,没有mappedBy也会遇到循环依赖问题。当双向关系中没有所有者时,就会发生这种情况。

在循环依赖关系中,您将(明确)设置实体的两面,然后保存

thisObj.set(thatObj);
thatObj.set(thisObj);