如何实现单向一对多自引用关系?
How do I implement a unidirectional one to many self referencing relationship?
我有一个 "Question" 实体,我可以坚持 "Question" table。一个问题可以有多个翻译。翻译只是另一种语言的另一个问题,它与带有 parent_id 字段的父问题相关联。因此,问题 table 具有列 question_id (int)、parent_id (int)、语言 (varchar)、提示等。在我的设计中,parent_id 是相同的作为翻译的 question_id。例如,假设我有一个英文(默认)ID 为 13 和 17 的问题,问题 13 有 3 种翻译,中文、日文和韩文。那么问题 table 将如下所示:
question_id parent_id 语言
13 13 英语; 14 13 中国人; 15 13 日本人; 16 13 韩语; 17 17 英语
在问题对象中,我想映射一个问题与其翻译的关系,这是一个@OneToMany 自引用关系。经过一些研究后,我通过以下方式实现了它:
@Entity
@Table(name = "question")
public class Question {
@Id
@GeneratedValue
@Column(name = "id")
private Integer id;
@ManyToOne(cascade=CascadeType.PERSIST)
@JoinColumn(name="parent_id")
private Question parent;
@OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
private Set<Question> translations;
Other properties...
Getters and setters....
}
但是,由于是自引用关系,我不明白以下内容:
- 这是单向关系还是双向关系?
- 注释 cascade = CascadeType.PERSIT 在 "parent" 字段上的效果是什么,或者在这种情况下它意味着什么?
- 是否可以将 "parent" 字段替换为 Integer "parent_id" 并仍然保持关系?换句话说,我是否可以只使用 Integer "parent_id" 跟踪父级而不是像现在这样拥有整个 Question 对象:private Question parent
这里需要把问题和翻译分开,创建一个Question实体:
@Entity
public class Question {
private int id;
//other independent translation properties
}
@Entity
public class QuestionTranslation{
private int id;
@ManyTone
private Question question;
private Language language;
private String translation'
//more translation based info
}
这样,您就不需要父子之间的复杂关系。
- Is this a unidirectional or bidirectional relationship?
你拥有的是自我参照的双向关系。它只是标准双向关系的一个特例。
- What would the effect be of the annotation cascade = CascadeType.PERSIT on "parent" field or what does it mean in this
case?
在这种情况下,按照您的示例,这意味着如果您在问题 14 中设置 parent
13,只需为问题 14 调用坚持,问题 13 也将被保留。
我鼓励查看 JPA 规范以了解会发生什么(这里是 JPA 2.1 spect)。
- Is it possible to replace the "parent" field with Integer "parent_id" and still maintain the relationship? In other words, can I
just keep track of the parent with Integer "parent_id" instead of
having the entire Question object like I have now: private Question
parent
是的,您可以进行以下替换,
//@ManyToOne(cascade=CascadeType.PERSIST)
//@JoinColumn(name="parent_id")
//private Question parent;
@Column(name="parent_id", insertable=false, updatable=false)
private Integer parentId;
//@OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
@OneToMany(fetch=FetchType.EAGER, cascade=CascadeType.PERSIST)
@JoinColumn(name="parent_id")
private Set<Question> translations;
一些注意事项,
translations
集合的级联持久化选项不是必需的。由于关系不再是双向的,您可以将问题 14、15 和 16 添加到问题 13 的集合中,并将其与其集合一起保存。
- 在常见情况下,
parentId
属性将在添加问题或将其移动到某个集合时更新(这会启动更新语句来设置字段 parent_id
的值)。不需要手动修改属性,因此我添加 insertable
和 updateble
选项并将其设置为 false.
我有一个 "Question" 实体,我可以坚持 "Question" table。一个问题可以有多个翻译。翻译只是另一种语言的另一个问题,它与带有 parent_id 字段的父问题相关联。因此,问题 table 具有列 question_id (int)、parent_id (int)、语言 (varchar)、提示等。在我的设计中,parent_id 是相同的作为翻译的 question_id。例如,假设我有一个英文(默认)ID 为 13 和 17 的问题,问题 13 有 3 种翻译,中文、日文和韩文。那么问题 table 将如下所示:
question_id parent_id 语言
13 13 英语; 14 13 中国人; 15 13 日本人; 16 13 韩语; 17 17 英语
在问题对象中,我想映射一个问题与其翻译的关系,这是一个@OneToMany 自引用关系。经过一些研究后,我通过以下方式实现了它:
@Entity
@Table(name = "question")
public class Question {
@Id
@GeneratedValue
@Column(name = "id")
private Integer id;
@ManyToOne(cascade=CascadeType.PERSIST)
@JoinColumn(name="parent_id")
private Question parent;
@OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
private Set<Question> translations;
Other properties...
Getters and setters....
}
但是,由于是自引用关系,我不明白以下内容:
- 这是单向关系还是双向关系?
- 注释 cascade = CascadeType.PERSIT 在 "parent" 字段上的效果是什么,或者在这种情况下它意味着什么?
- 是否可以将 "parent" 字段替换为 Integer "parent_id" 并仍然保持关系?换句话说,我是否可以只使用 Integer "parent_id" 跟踪父级而不是像现在这样拥有整个 Question 对象:private Question parent
这里需要把问题和翻译分开,创建一个Question实体:
@Entity
public class Question {
private int id;
//other independent translation properties
}
@Entity
public class QuestionTranslation{
private int id;
@ManyTone
private Question question;
private Language language;
private String translation'
//more translation based info
}
这样,您就不需要父子之间的复杂关系。
- Is this a unidirectional or bidirectional relationship?
你拥有的是自我参照的双向关系。它只是标准双向关系的一个特例。
- What would the effect be of the annotation cascade = CascadeType.PERSIT on "parent" field or what does it mean in this case?
在这种情况下,按照您的示例,这意味着如果您在问题 14 中设置 parent
13,只需为问题 14 调用坚持,问题 13 也将被保留。
我鼓励查看 JPA 规范以了解会发生什么(这里是 JPA 2.1 spect)。
- Is it possible to replace the "parent" field with Integer "parent_id" and still maintain the relationship? In other words, can I just keep track of the parent with Integer "parent_id" instead of having the entire Question object like I have now: private Question parent
是的,您可以进行以下替换,
//@ManyToOne(cascade=CascadeType.PERSIST)
//@JoinColumn(name="parent_id")
//private Question parent;
@Column(name="parent_id", insertable=false, updatable=false)
private Integer parentId;
//@OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
@OneToMany(fetch=FetchType.EAGER, cascade=CascadeType.PERSIST)
@JoinColumn(name="parent_id")
private Set<Question> translations;
一些注意事项,
translations
集合的级联持久化选项不是必需的。由于关系不再是双向的,您可以将问题 14、15 和 16 添加到问题 13 的集合中,并将其与其集合一起保存。- 在常见情况下,
parentId
属性将在添加问题或将其移动到某个集合时更新(这会启动更新语句来设置字段parent_id
的值)。不需要手动修改属性,因此我添加insertable
和updateble
选项并将其设置为 false.