我有一个"问题"我可以坚持的实体"问题"表。一个问题可以有多个翻译。翻译只是使用parent_id字段与其父问题相关联的另一种语言中的另一个问题。因此,Question表包含了question_id(int),parent_id(int),language(varchar),prompt等列。在我的设计中,parent_id与翻译的question_id相同。例如,让我说我的英语(默认)为id 13和17,问题13有中文,日文和韩文三种翻译。然后问题表如下所示:
question_id parent_id language
13 p 13英语; 14 13中国人; 15 13日本人; 16 13韩国人; 17 17英语在Question对象中,我想要映射问题与其翻译的关系,这是@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....
}
但是,由于它是一种自引用关系,我不理解以下内容:
答案 0 :(得分:1)
- 这是单向还是双向关系?
您拥有的是自我引用的双向关系。这只是标准双向关系的一个特例。
- “父”字段上的注释级联= CascadeType.PERSIT会产生什么影响或者它在这意味着什么 情况?
在这种情况下,按照你的例子,这意味着如果你在问题14中设置parent
13,只是为问题14调用persist,那么Querstion 13也会被保留。
我鼓励看到JPA规范知道会发生什么(这里是JPA 2.1 spect)。
- 是否可以用Integer“parent_id”替换“父”字段并仍保持关系?换句话说,我可以 只需使用Integer“parent_id”而不是跟踪父级 拥有像我现在一样的整个Question对象:private Question 父
是的,您可以进行以下替换,
//@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 。答案 1 :(得分:0)
在这里,您需要将问题与翻译分开,创建一个问题实体:
@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
}
这样,你就不需要父,子东西之间的复杂化。