Sunday, March 6, 2016

Hibernate Object Relationships

one-to-one

1: based on Primary key one-to-one

Two tables, A and B.
B's foreign id is A's id.

Student obj: {id,name,idCard}

<one-to-one name="idCard"/>


IdCard obj: {id,expdate,student}

Generate primary id by a foreign key

<!-- set id as foreign key -->
<id name="id">
  <generator class="foreign">
  <param name="property">student</param>
  </generator>
</id>
<one-to-one name="student" constrained="true">

In <one-to-one>
constriained="true": copy target id as self id, and make as foreign key relationship in table
constriained="false": simply copy target id as self id


2: based on Foreign key one-to-one

To make a one-to-one relationship based on Foreign key:
simply use <many-to-one> and set unique="true"

In IdCard.hbm.xml

<many-to-one name="student" unique="true" />




many-to-one

Student to Department

<hibernate-mapping package="com.gvace.domain">
 <class name="Student">
  <id name="id" type="java.lang.Integer">
   <generator class="increment"></generator>
  </id>
  <property name="name" type="java.lang.String">
   <column name="name" length="64" not-null="true"/>
  </property>
        <many-to-one name="department" column="dept_id" />
        <!-- 
         "name": property name
         "column": column name in this table
          -->
 </class>
</hibernate-mapping>


Issue: in lazy mode, after session closed, the foreign property still not load.
Solution:

  1. Hibernate.initialize(student.getDepartment()); //initialize proxy
  2. <class name="Department" lazy="false"> //disable lazy mode
  3. Filter(web project): openinSessionInView

one-to-many

Get all students from a department

private Set students = new HashSet(0); //can be any collection

In hbm.xml, use <set> to represent one-to-many property

<hibernate-mapping package="com.gvace.domain">
 <class name="Department" lazy="false">
  <id name="id" type="java.lang.Integer">
   <generator class="increment"></generator>
  </id>
  <property name="name" type="java.lang.String">
   <column name="name" length="64" not-null="true"/>
  </property>
  <!-- One to Many -->
  <set name="students" >
   <key column="dept_id"></key>
   <one-to-many class="Student"/>
  </set>
 </class>
</hibernate-mapping>


cascade="save-update"
In <set>: If we want automatically save each record in <set> property, use cascade="save-update"


many-to-many


Normally we CONVERT many-to-many relationship to two one-to-many, and one many-to-one
We create a new table for only relationship mapping


Student obj: {id, name, Set<StudentCourse> studentCourses}
Course obj: {id, name,  Set<StudentCourse> studentCourses}
StudentCourse obj: {id, Student, Course, grade}

Target Student table: {id, name}
Target Course table: {id, name}
Target StudentCourse table: {id, student_id, course_id, grade}

Student.hbm.xml

<set name="studentCourses">
  <key column="student_id" />
  <one-to-many class="StudentCourse" />
</set>

Course.hbm.xml

<set name="studentCourses">
  <key column="course_id" />
  <one-to-many class="StudentCourse" />
</set>


StudentCourse.hbm.xml

<many-to-one name="course" column="course_id" />
<many-to-one name="student" column="student_id" />




No comments:

Post a Comment