I have a "Question" entity that I can persist to "Question" table. A question can have multiple translations. A translation is just another question in another language that is associated with its parent question with parent_id field. Thus the Question table has columns question_id (int), parent_id (int), language (varchar), prompt, etc. In my design, the parent_id is the same as the question_id for a translation. For example, let's say I have question with id 13 and 17 in English (default) and question 13 has 3 translations, in Chinese, Japanese, and Korean. Then the Question table would look like the following:
question_id parent_id language
13 13 English; 14 13 Chinese; 15 13 Japanese; 16 13 Korean; 17 17 English
In the Question object, I want map a Question's relation to its translations which is a @OneToMany self-referenced relationship. I have implemented it the following way after doing some research:
@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....
}
However, I do not understand the following due to it being a self-referencing relationship:
- Is this a unidirectional or bidirectional relationship?
What you have is self-referential bidirectional relationship. It is justa a special case of standard bidirectional relationships.
- What would the effect be of the annotation cascade = CascadeType.PERSIT on "parent" field or what does it mean in this case?
In this case and following your example, it means that if you set the parent
13 in your Question 14, just invoking persist for Question 14 the Querstion 13 will be persisted too.
I encourage to see the JPA specification to know what to expect (here is 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
Yes, you could do the following replacements,
//@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;
Some notes about,
translations
collections isn't necessary. Due to the relationship isn't bidirectional anymore, you can add Questions 14, 15 and 16 to the Question 13's collection and persist it along with its collection.parentId
attribute will be updated when a question is add or move it to some collection (this fire up an update statement to set value of field parent_id
). It shouldn't be necessary to modify the attribute manually therefore I add and set the insertable
and updateble
options to false.Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments