Tuesday, October 18, 2011

Many to Many Bidirectional association

Mapping using Hibernate XML mapping:

Let us go to the package com.demo.manyToManyBidirectional and execute the class ManyToManyBidirectionalExecutor.java.

Things to look into:

* The ORM classes Student.java and Course.java
* The xml mapping file manyToManyBidirectional.hbm.xml

ORM:

public class Student {

private long id;

private String studentName;

private Set courses = new HashSet();

//getter and setter methods
}


public class Course {

private long id;

private String courseName;

private Set students = new HashSet();

//getter and setter methods
}

* Note that both the entities have reference to each other (i.e) Student class has a reference to Course and Course class has reference to Student.

XML:

<hibernate-mapping>
<class name="com.demo.manyToManyBidirectional.Student" table="STUDENTS" lazy="false">
<id name="id" column="STUDENT_ID">
<generator class="native" />
</id>
<property name="studentName" column="STUDENT_NAME" />
<set name="courses" table="STUDENT_COURSE" lazy="false" cascade="save-update">
<key column="STUDENT_ID" not-null="true" />
<many-to-many class="com.demo.manyToManyBidirectional.Course"
column="COURSE_ID" />
</set>
</class>

<class name="com.demo.manyToManyBidirectional.Course" table="COURSES" lazy="false">
<id name="id" column="COURSE_ID">
<generator class="native" />
</id>
<property name="courseName" column="COURSE_NAME" />
<set name="students" table="STUDENT_COURSE" lazy="false" inverse="true">
<key column="COURSE_ID" not-null="true" />
<many-to-many class="com.demo.manyToManyBidirectional.Student"
column="STUDENT_ID" />
</set>
</class>
</hibernate-mapping>

* refers the to-many association and also declares the collection table.
* cascase declares that inserting the objects will be taken care by the Student entity.
* refers the foreign key column of the collection table.

* declares the many-to-many association.
* inverse="true" on the Course side indicates that it will not participate in updating the collection table STUDENT_COURSE and hence only from the Student side the collection table will be updated. Other wise if both sides try to update the collection table either duplicate rows will be inserted or any unique constraint will be violated.

Once the
ManyToManyBidirectionalExecutor.java is executed, verify the results in the eclipse console and in the HSQL DB manager by running simple select queries on the following tables STUDENTS, COURSES and STUDENT_COURSE as follows.




Mapping by Annotation:

Let us go to the package annotation.com.demo.manyToManyBidirectioinal and execute the class
ManyToManyAnnotationBidirectionalExecutor.java

Things to look into:

The annotated ORM classes Student.java and Course.java

@Entity(name="annotation.com.demo.manyToManyBidirectioinal.Student")
@Table(name="STUDENTS")
public class Student {

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="STUDENT_ID")
private long id;

@Column(name="STUDENT_NAME")
private String studentName;

@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
@JoinTable(name="STUDENT_COURSE",joinColumns=@JoinColumn(name="STUDENT_ID"),inverseJoinColumns=@JoinColumn(name="COURSE_ID"))
private Set courses = new HashSet();

//getter and setter methods
}


@Entity(name="annotation.com.demo.manyToManyBidirectioinal.Course")
@Table(name="COURSES")
public class Course {

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="COURSE_ID")
private long id;

@Column(name="COURSE_NAME")
private String courseName;

@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
@JoinTable(name="STUDENT_COURSE",joinColumns=@JoinColumn(name="COURSE_ID"),inverseJoinColumns=@JoinColumn(name="STUDENT_ID"))
private Set students = new HashSet();

//getter and setter methods
}



*
@ManyToMany declares the many-to-many association
*
cascase declares that inserting the objects will be taken care by the Student entity.
* @JoinTable refers the table where the collection values will be stored.
* @JoinColumn represents the foreign key column of the collection table.
* Note that both the classes have references to each other and the common collection table STUDENT_COURSE.


Once the ManyToManyAnnotationBidirectionalExecutor.java is executed , verify the results as mentioned above.