Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Do I Create Many to Many Hibernate Mapping for Additional Property from the Join Table?

I need a many to many hibernate mapping needed 3 joins. I've tried to find out a solution without intermediate entity like LecturerCourse.

I have a many to many relation in my database between my lecturer and course tables. A course can be given by several lecturer while a lecturer can give several courses.

I have courses stored before hand. However, I need to assign courses to lecturer. When I assign courses I also store the capacity of that course.

My database diagram:

enter image description here

I use hibernate and spring. I need a hibernate mapping when a course is assign any lecturer. I need to add values to capacity field.

My lecturer mapping :

@Entity
@Table(name="LECTURER")
public class Lecturer {

    @Id 
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="LECTURER_ID_SEQ")
    @SequenceGenerator(name="LECTURER_ID_SEQ", sequenceName="LECTURER_ID_SEQ")
    private Long Id;

    @Column(name="NAME")
    private String name;

    @Column(name="SURNAME")
    private String surname;


    @Column(name="EMAIL")
    private String email;

    @Column(name="USERNAME")
    private String username;

    @Column(name="PASSWORD")
    private String Password;

    @ManyToMany
    @JoinTable(
          name="LECTURER_COURSE",
          joinColumns=@JoinColumn(name="LECTURER_ID"),
          inverseJoinColumns=@JoinColumn(name="COURSE_ID")
      )
    private List<Course> courses;

    //getters - setters
}

My course mapping :

@Entity
@Table(name="COURSE")
public class Course {

    @Id 
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="COURSE_ID_SEQ")
    @SequenceGenerator(name="COURSE_ID_SEQ", sequenceName="COURSE_ID_SEQ")
    private Long id;

    @Column(name="NAME")
    private String name;

    @Column(name="CODE")
    private String code;
}

Any idea how to solve my problem ?

like image 877
erencan Avatar asked Apr 24 '12 08:04

erencan


People also ask

What should be done for many-to-many joins in Hibernate?

In order to map a many-to-many association, we use the @ManyToMany, @JoinTable and @JoinColumn annotations. Let's have a closer look at them. The @ManyToMany annotation is used in both classes to create the many-to-many relationship between the entities.

Is is possible to store additional information together with the many-to-many relationship?

Solution: Modeling a many-to-many association in your table model requires an association table, that references the primary keys of the associated records. If you want to store any additional information for this relationship, you can do that by adding columns to the association table.

Which of the following element is used to map many-to-many relationship in Hibernate?

Define Hibernate Mapping File The <set> element will be used to define the rule for manyto-many relationship. The mapping document is an XML document having <hibernate-mapping> as the root element which contains two <class> elements corresponding to each class.

How do you map an entity to multiple tables in Hibernate?

Yes, you can map an entity to 2 database tables in 2 simple steps: You need to annotate your entity with JPA's @Table and @SecondaryTable annotations and provide the names of the first and second table as the value of the name parameters.


1 Answers

You need to use @EmbeddedId and @Embeddable annotations to solve this issue:

Lecturer Class:

@Entity
@Table(name="LECTURER")
public class Lecturer {

@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.lecturer", cascade=CascadeType.ALL)
Set<LecturerCourse> lecturerCourses == new HashSet<LecturerCourse>();

//all others properties Setters and getters are less relevant.

}

Course class:

@Entity
@Table(name="COURSE")
public class Course {

@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.course", cascade=CascadeType.ALL)
Set<LecturerCourse> lecturerCourses == new HashSet<LecturerCourse>();

//all others properties Setters and getters are less relevant.

}

LecturerCourse Class:

@Entity
@Table(name = "lecturer_course")
@AssociationOverrides({
        @AssociationOverride(name = "pk.lecturer", 
            joinColumns = @JoinColumn(name = "LECTURER_ID")),
        @AssociationOverride(name = "pk.course", 
            joinColumns = @JoinColumn(name = "COURSE_ID")) })
public class LecturerCourse {

    private LecturerCourseID pk = new LecturerCourseID();

    @Column(name = "CAPACITY", nullable = false, length = 10)
    private String capacity;

    @EmbeddedId
    public LecturerCourseID getPk() {
        return pk;
    }

}

Now the Primary Key:

@Embeddable
public class LecturerCourseID implements java.io.Serializable {

    private Lecturer lecturer;
    private Course course;

    @ManyToOne
    public Stock getLecturer() {
        return lecturer;
    }

    public void setLecturer(Lecturer lecturer) {
        this.lecturer= lecturer;
    }

    @ManyToOne
    public Course getCourse() {
        return course;
    }

    public void setCourse(Course course) {
        this.course= course;
    }

}

now Your Main should be something like this:

Lecturer lecturer1 = new Lecturer();
Course math = new Course();
LecturerCourse lecturer1math  = new LecturerCourse();
lecturer1math.setCapacity("capacity");
lecturer1math.setLecturer(lecturer1);
lecturer1math.setCourse(math);
lecturer1.getLecturerCourses().add(lecturer1math);

//saving object
session.save(lecturer1);

You need to be sure that class marked as @Embeddable should implement Serializable marker interface.

Hope it helps.

like image 119
danny.lesnik Avatar answered Sep 20 '22 05:09

danny.lesnik