hibernate one to many single direction

mr.nothing picture mr.nothing · May 7, 2013 · Viewed 9.3k times · Source

I'm trying to make some hibernate stuff and create sql scripts automatically based on the hibernate annotations. Here is what I have:

Schedule class:

@Entity
@Table(name = ScheduleTableConsts.TABLE_NAME)
public class Schedule implements Serializable {

@Id
@Column(name = ScheduleTableConsts.ID_COLUMN)
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;

@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name = ScheduleSlotTableConsts.ID_COLUMN)
private List<ScheduleSlot> scheduleSlots;

@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name = LessonTableConsts.ID_COLUMN)
private List<Lesson> lessons;  

Constructors, getters, setters...

ScheduleSlot class:

@Entity
@Table(name = ScheduleSlotTableConsts.TABLE_NAME,
       uniqueConstraints = {@UniqueConstraint(columnNames = {TimeSlotTableConsts.ID_COLUMN,
                                                             PlaceSlotTableConsts.ID_COLUMN})})
public class ScheduleSlot implements Serializable {
@Id
@Column(name = ScheduleSlotTableConsts.ID_COLUMN)
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;

@OneToOne
@JoinColumn(name = TimeSlotTableConsts.ID_COLUMN)
private TimeSlot timeSlot;

@OneToOne
@JoinColumn(name = PlaceSlotTableConsts.ID_COLUMN)
private PlaceSlot placeSlot;  

Constructors, getters, setters...  

Lesson class:

@Entity
@Table(name = LessonTableConsts.TABLE_NAME)
public class Lesson implements Serializable {

@Id
@Column(name = LessonTableConsts.ID_COLUMN)
@GeneratedValue(strategy = GenerationType.AUTO)
private int            id;

@OneToMany(fetch = FetchType.LAZY)
private Set<Professor> professors;

@OneToMany(fetch = FetchType.LAZY)
private Set<Course>    courses;

@OneToMany(fetch = FetchType.LAZY)
private Set<Group>     groups;

@Column(name = LessonTableConsts.LAB_COLUMN)
private boolean        lab;  

Constructors, getters, setters...

What I'm trying to achieve is to let schedule know about it's slots and lessons and not to let slots and lessons know about the schedule they are belong to. The code above seems to be ok, but when I'm trying to generate sql script (using maven and hibernate3-maven-plugin for that purposes) and run it the following happens:

  1. It creates a SCHEDULE table with no pointers to SCHEDULESLOT or LESSON tables;
  2. It creates SCHEDULESLOT and LESSON tables with no pointers to SCHEDULE table.

Could somebody, please, tell me what I am doing wrong?

Thank in advance!

Answer

Matin Kh picture Matin Kh · May 7, 2013

There is a thing you are forgetting to notice:

When using @OneToMany annotation, you cannot simply use @JoinColumn. However, on the other side, I mean @ManyToOne: you can use @JoinColumn.

It should be clear to you why this works this way, and not the other way around. (How can an entity keep so many IDs in just one column?)

So you have two options here:
1) Use a specific table to store relation between your One and Many entities. Something like this:

@OneToMany(cascade=CascadeType.ALL)
@JoinTable(name = "SCHEDULE_SLOTS_MAPPING", joinColumns = @JoinColumn(name = "SCHEDULE_ID"), inverseJoinColumns = @JoinColumn(name = "SCHEDULE_SLOT_ID"))
private List<ScheduleSlot> scheduleSlots;

2) Use the @JoinColumn on the Many side of the relationship: (e.g. your ScheduleSlot class)

@ManyToOne
@JoinColumn(name="SCHEDULE_ID")
private Schedule schedule;