The Hibernate One-To-One Mapping Example using Annotation tutorial show you how to use Hibernate One-To-One Unidirectional Shared primary key mapping. With One-To-One Unidirectional Shared primary key mapping, two tables share the same primary key.
In this Hibernate One-To-One Mapping Example using Annotation tutorial, we are discussing an example of a one-to-one association with a Student entity that references one StudentDetail entity. The StudentDetail does not reference back to the Student so that the reference is said to be unidirectional, in one direction only.
Other interesting posts you may like
Create Database Table
We create two tables with these below scripts:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
CREATE TABLE STUDENT ( id INT(11) NOT NULL, name VARCHAR(100) NOT NULL, entering_date DATE NOT NULL, nationality TEXT NOT NULL, code VARCHAR(30) NOT NULL ) CREATE TABLE STUDENT_DETAIL ( id INT(11) DEFAULT NULL, first_name VARCHAR(50) NOT NULL, last_name VARCHAR(50) NOT NULL, gender VARCHAR(50) NOT NULL, school VARCHAR(100) NOT NULL, address VARCHAR(250) NOT NULL, country VARCHAR(100) NOT NULL, post_code VARCHAR(10) NOT NULL ) |
Project directory structure
Our project is created with the below project structure:
Maven dependencies
We provide the required Hibernate and MySQL dependency in pom.xml like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.javabycode.hibernate</groupId> <artifactId>HibernateWithAnnotation</artifactId> <version>1.0.0</version> <packaging>jar</packaging> <name>HibernateWithAnnotation</name> <properties> <hibernate.version>4.3.11.Final</hibernate.version> <mysql.version>5.1.31</mysql.version> </properties> <dependencies> <!-- Hibernate --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>${hibernate.version}</version> </dependency> <!-- MySQL --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> </dependencies> </project> |
Create Model class
Model class Student and StudentDetail are simple POJO class. Here we are using class Student and StudentDetail with JPA annotations to map them to a database tables (these tables were created in above step).
Student Model class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
package com.javabycode.hibernate.model; import java.io.Serializable; import java.util.Date; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToOne; import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; @Entity @Table(name = "STUDENT") public class Student implements Serializable { private static final long serialVersionUID = 6832006422622219737L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; @Column(name = "NAME", nullable = false) private String name; @Column(name = "ENTERING_DATE", nullable = false) private Date enteringDate; @Column(name = "NATIONALITY", nullable = false) private String nationality; @Column(name = "CODE", nullable = false) private String code; @OneToOne(cascade = CascadeType.ALL) @PrimaryKeyJoinColumn private StudentDetail studentDetail; public Student(){ } public Student(String name, Date enteringDate,String nationality, String code){ this.name = name; this.enteringDate = enteringDate; this.nationality = nationality; this.code = code; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void setCode(String code) { this.code = code; } public void setEnteringDate(Date enteringDate) { this.enteringDate = enteringDate; } public void setNationality(String nationality) { this.nationality = nationality; } public String getCode() { return code; } public Date getEnteringDate() { return enteringDate; } public String getNationality() { return nationality; } public void setStudentDetail(StudentDetail studentDetail) { this.studentDetail = studentDetail; } public StudentDetail getStudentDetail() { return studentDetail; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + id; result = prime * result + ((code == null) ? 0 : code.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (!(obj instanceof Student)) return false; Student other = (Student) obj; if (id != other.id) return false; if (code == null) { if (other.code != null) return false; } else if (!code.equals(other.code)) return false; return true; } @Override public String toString() { return "Student [id=" + id + ", name=" + name + ", enteringDate=" + enteringDate + ", nationality=" + nationality + ", code=" + code + "]"; } } |
StudentDetail Model class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
package com.javabycode.hibernate.model; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "STUDENT_DETAIL") public class StudentDetail { @Id @Column(name = "ID") private int id; @Column(name = "FIRST_NAME") private String firstName; @Column(name = "LAST_NAME") private String lastName; @Column(name = "GENDER") private String gender; @Column(name = "SCHOOL") private String school; @Column(name = "ADDRESS") private String address; @Column(name = "COUNTRY") private String country; @Column(name = "POST_CODE") private String postCode; public StudentDetail() { } public StudentDetail(String firstName, String lastName, String gender, String school, String address, String postCode, String country) { this.firstName = firstName; this.lastName = lastName; this.gender = gender; this.school = school; this.address = address; this.postCode = postCode; this.country = country; } public int getId() { return id; } public void setId(int id) { this.id = id; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getFirstName() { return firstName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getLastName() { return lastName; } public void setAddress(String address) { this.address = address; } public String getAddress() { return address; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } public void setGender(String gender) { this.gender = gender; } public String getGender() { return gender; } public void setPostCode(String postCode) { this.postCode = postCode; } public String getPostCode() { return postCode; } public void setSchool(String school) { this.school = school; } public String getSchool() { return school; } @Override public String toString() { return "StudentDetail [id=" + id + ",firstName=" + firstName + ",lastName=" + lastName + ",gender=" + gender + ", address=" + address + ", country=" + country + ", postCode=" + postCode + "]"; } } |
Let’s dig deepr:
@OneToOne on studentDetail property of Student class indicates that there is a one-to-one association from Student to StudentDetail.
@PrimaryKeyJoinColumn indicates that the primary key of the Student entity is used as a foreign key to the StudentDetail entity.
Here we are using cascade = CascadeType.ALL. It means that StudentDetail entity can not exist without Student entity and StudentDetail entity will be update/delete on subsequent update/delete on Student entity.
Create Hibernate configuration file
We need to provide for hiberate all stuffs like database dialect, driver class, url and account information to connect database. These stuffs is declared in file hibernate.cfg.xml like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-configuration SYSTEM "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.username">javabycode</property> <property name="hibernate.connection.password">mypassword</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/javabycode</property> <property name="show_sql">false</property> <property name="format_sql">false</property> <mapping class="com.javabycode.hibernate.model.Student"/> <mapping class="com.javabycode.hibernate.model.StudentDetail"/> </session-factory> </hibernate-configuration> |
This file is placed in src/main/resources folder.
Create Hibernate Utility class
For configuring hibernate on startup and managing session factory we create the HibernateUtil class like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
package com.javabycode.hibernate; import org.hibernate.SessionFactory; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; public class HibernateUtil { private static final SessionFactory sessionFactory; private static final ServiceRegistry serviceRegistry; static { try { Configuration configuration = new Configuration(); configuration.configure(); serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build(); sessionFactory = new Configuration().configure().buildSessionFactory(serviceRegistry); } catch (Throwable ex) { System.err.println("Session Factory could not be created." + ex); throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } } |
Create program to demonstrate Hibernate One-To-One Mapping
Here is a final part of the Hibernate One-To-One Mapping Example using Annotation tutorial. We will create the main class like below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
package com.javabycode.hibernate; import java.util.Date; import java.util.List; import org.hibernate.Session; import com.javabycode.hibernate.model.StudentDetail; import com.javabycode.hibernate.model.Student; public class HibernateExample { @SuppressWarnings("unchecked") public static void main(String[] args) { Student student = new Student("David Pham", new Date(), "USA", "1234569"); StudentDetail studentDetail = new StudentDetail("David", "Pham", "Male", "High School", "70xx Silver street", "USA", "10001"); Session session = HibernateUtil.getSessionFactory().openSession(); session.beginTransaction(); session.save(student); studentDetail.setId(student.getId()); student.setStudentDetail(studentDetail); session.save(student); session.getTransaction().commit(); session.flush(); List<Student> students = (List<Student>) session.createQuery("from Student ").list(); for (Student s : students) { System.out.println("Student : " + s); } List<StudentDetail> studentDetails = (List<StudentDetail>) session.createQuery("from StudentDetail ").list(); for (StudentDetail std : studentDetails) { System.out.println("Student Detail: " + std); } session.close(); System.exit(0); } } |
In the above program, we persist a Student early, so that id of that student is generated. Then we set the StudentDetail id with student id( it means that foreign key constraint be respected). Finally, the studentDetail property of Student is set by StudentDetail object and save Student.
The Cascade attribute is used on studentDetail property of Student class so that Hibernate will save StudentDetail object automatically and we no need to save it explicitly.
Run the above program as Java application. We will get the ouput like this:
1 2 |
Student : Student [id=28, name=David Pham, enteringDate=Wed Oct 05 10:56:35 ICT 2016, nationality=USA, code=1234569] Student Detail: StudentDetail [id=28,firstName=David,lastName=Pham,gender=Male, address=70xx Silver street, country=10001, postCode=USA] |
That’s it on the Hibernate One-To-One Mapping Example using Annotation tutorial.
Download complete source code, please click link below
OneToOneMappingExample.zip (260 downloads)