Thursday 23 August 2012

Hibernate Mapping One-to-Many using Annotations


In this example you will learn how to map one-to-many relationship using Hibernate Annotations. Consider the following relationship between Student and Phone entity.

According to the relationship a student can have any number of phone numbers.
To create this relationship you need to have a STUDENT, PHONE and STUDENT_PHONE table. The relational model is shown below.

To create the STUDENT and PHONE table you need to create the following Java Class files.
Student class is used to create the STUDENT and STUDENT_PHONE table.
01.package com.vaannila.student;
02. 
03.import java.util.HashSet;
04.import java.util.Set;
05. 
06.import javax.persistence.CascadeType;
07.import javax.persistence.Column;
08.import javax.persistence.Entity;
09.import javax.persistence.GeneratedValue;
10.import javax.persistence.Id;
11.import javax.persistence.JoinColumn;
12.import javax.persistence.JoinTable;
13.import javax.persistence.OneToMany;
14.import javax.persistence.Table;
15. 
16.@Entity
17.@Table(name = "STUDENT")
18.public class Student {
19. 
20.    private long studentId;
21.    private String studentName;
22.    private Set<Phone> studentPhoneNumbers = new HashSet<Phone>(0);
23. 
24.    public Student() {
25.    }
26. 
27.    public Student(String studentName, Set<Phone> studentPhoneNumbers) {
28.        this.studentName = studentName;
29.        this.studentPhoneNumbers = studentPhoneNumbers;
30.    }
31. 
32.    @Id
33.    @GeneratedValue
34.    @Column(name = "STUDENT_ID")
35.    public long getStudentId() {
36.        return this.studentId;
37.    }
38. 
39.    public void setStudentId(long studentId) {
40.        this.studentId = studentId;
41.    }
42. 
43.    @Column(name = "STUDENT_NAME", nullable = false, length = 100)
44.    public String getStudentName() {
45.        return this.studentName;
46.    }
47. 
48.    public void setStudentName(String studentName) {
49.        this.studentName = studentName;
50.    }
51. 
52.    @OneToMany(cascade = CascadeType.ALL)
53.    @JoinTable(name = "STUDENT_PHONE", joinColumns = { @JoinColumn(name = "STUDENT_ID") }, inverseJoinColumns = { @JoinColumn(name = "PHONE_ID") })
54.    public Set<Phone> getStudentPhoneNumbers() {
55.        return this.studentPhoneNumbers;
56.    }
57. 
58.    public void setStudentPhoneNumbers(Set<Phone> studentPhoneNumbers) {
59.        this.studentPhoneNumbers = studentPhoneNumbers;
60.    }
61. 
62.}
The @OneToMany annotation is used to create the one-to-many relationship between the Student and Phone entities. The @JoinTable annotation is used to create the STUDENT_PHONE link table and @JoinColumn annotation is used to refer the linking columns in both the tables.
Phone class is used to create the PHONE table.
01.package com.vaannila.student;
02. 
03.import javax.persistence.Column;
04.import javax.persistence.Entity;
05.import javax.persistence.GeneratedValue;
06.import javax.persistence.Id;
07.import javax.persistence.Table;
08. 
09.@Entity
10.@Table(name = "PHONE")
11.public class Phone {
12. 
13.    private long phoneId;
14.    private String phoneType;
15.    private String phoneNumber;
16. 
17.    public Phone() {
18.    }
19. 
20.    public Phone(String phoneType, String phoneNumber) {
21.        this.phoneType = phoneType;
22.        this.phoneNumber = phoneNumber;
23.    }
24.     
25.    @Id
26.    @GeneratedValue
27.    @Column(name = "PHONE_ID")
28.    public long getPhoneId() {
29.        return this.phoneId;
30.    }
31. 
32.    public void setPhoneId(long phoneId) {
33.        this.phoneId = phoneId;
34.    }
35. 
36.    @Column(name = "PHONE_TYPE", nullable = false, length=10)
37.    public String getPhoneType() {
38.        return this.phoneType;
39.    }
40. 
41.    public void setPhoneType(String phoneType) {
42.        this.phoneType = phoneType;
43.    }
44.     
45.    @Column(name = "PHONE_NUMBER", nullable = false, length=15)
46.    public String getPhoneNumber() {
47.        return this.phoneNumber;
48.    }
49. 
50.    public void setPhoneNumber(String phoneNumber) {
51.        this.phoneNumber = phoneNumber;
52.    }
53. 
54.}
Now create the hibernate configuration file with the Student and Phone class mapping.
01.<?xml version="1.0" encoding="UTF-8"?>
02.<!DOCTYPE hibernate-configuration PUBLIC
03.        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
05.<hibernate-configuration>
06.    <session-factory>
07.        <property name="hibernate.connection.driver_class"> org.hsqldb.jdbcDriver</property>
08.        <property name="hibernate.connection.url"> jdbc:hsqldb:hsql://localhost<;/property>
09.        <property name="hibernate.connection.username">sa</property>
10.        <property name="connection.password"></property>
11.        <property name="connection.pool_size">1</property>
12.        <property name="hibernate.dialect"> org.hibernate.dialect.HSQLDialect</property>
13.        <property name="show_sql">true</property>
14.        <property name="hbm2ddl.auto">create-drop</property>
15.        <mapping class="com.vaannila.student.Student" />
16.        <mapping class="com.vaannila.student.Phone" />
17.    </session-factory>
18.</hibernate-configuration>
Create the Main class to run the example.
01.package com.vaannila.student;
02. 
03.import java.util.HashSet;
04.import java.util.Set;
05. 
06.import org.hibernate.HibernateException;
07.import org.hibernate.Session;
08.import org.hibernate.Transaction;
09. 
10.import com.vaannila.util.HibernateUtil;
11. 
12.public class Main {
13. 
14.    public static void main(String[] args) {
15.        Session session = HibernateUtil.getSessionFactory().openSession();
16.        Transaction transaction = null;
17.        try {
18.            transaction = session.beginTransaction();
19.             
20.            Set<Phone> phoneNumbers = new HashSet<Phone>();
21.            phoneNumbers.add(new Phone("house","32354353"));
22.            phoneNumbers.add(new Phone("mobile","9889343423"));
23.             
24.            Student student = new Student("Eswar", phoneNumbers);
25.            session.save(student);
26.             
27.            transaction.commit();
28.        } catch (HibernateException e) {
29.            transaction.rollback();
30.            e.printStackTrace();
31.        } finally {
32.            session.close();
33.        }
34. 
35.    }
36. 
37.}
On executing the Main class you will see the following output.
The STUDENT table has one record.

The PHONE table has two records.

The STUDENT_PHONE table has two records to link the student and phone numbers.

A single student record points to two phone numbers, this illustrates the one-to-many mapping.
The folder structure of the example is shown below.


No comments:

Post a Comment