I was trying to use Hibernate Annotations, which I think is great … I am happy with it… but I learnt some stuff which I know I will forget. So I am blogging it here, hopefully I will make sense and serve as a reminder for me when I need it. Maybe it might help someone else too… who knows…
Bidirectional One-To-Many
here I am trying to create a Bidirectional One-To-Many relationship between Question and Choice, a Question has many choices.
- Setup entities
@Entity
@Table (name = "QUESTION")
public class Question implements Serializable
{@Id
@GeneratedValue (strategy = GenerationType.AUTO)
@Column (name = “QUESTION_ID”)
private Long id;@Column (name = “TEXT”)
private String text;
……………
@Entity
@Table (name = "CHOICE")
public class Choice implements Serializable
{@Id
@GeneratedValue (strategy = GenerationType.AUTO)
@Column (name = “CHOICE_ID”)
private Long id;@Column (name = “TEXT”)
private String text;
…………… - Setup the ONE side on Question – I read ONE Question has MANY CHOICE(S).
Question
@OneToMany (mappedBy="question")
private Set choices = new HashSet();
mappedBy – means “I am not the owner side”, I am mapped by question from the other side of the relationship. It will also not create the database column which makes sense, I would expect a foreign key on the CHOICE table instead.
- Setup the Many side on Choice – I read on Choice.java MANY Choice has ONE Question
@ManyToOne
@JoinColumn (name="QUESTION_ID")
private Question question;
the @JoinColumn indicate the owning side of the relationship, it is responsible for updating the database column. It will create the QUESTION_ID column on the CHOICE table
- Reversing the Relationship so that the owning side is the Question instead
Question
@OneToMany
@JoinColumn (name = "QUESTION_ID")
private Set choices = new HashSet();
Choice
@ManyToOne
@JoinColumn (name="QUESTION_ID", updatable = false, insertable = false)
private Question question;
- Finally I need to use a List instead of Set – so I can preserve the order of the Choice(s).Question
@OneToMany (
cascade = {CascadeType.ALL},
fetch = FetchType.EAGER
)
@JoinColumn (name = "QUESTION_ID")
@org.hibernate.annotations.Cascade(
value = org.hibernate.annotations.CascadeType.DELETE_ORPHAN
)
@org.hibernate.annotations.IndexColumn(name = "CHOICE_POSITION")
private List choices = new ArrayList();
Choice
@ManyToOne
@JoinColumn (name="QUESTION_ID", nullable = false, updatable = false, insertable = false)
private Question question;
the @org.hibernate.annotations.IndexColumn defines the colum CHOICE_POSITION that will be used to maintain the order of the list. Some how reversing the ownership is the only way to get the IndexColumn to work








