The Hibernate Many to One Bidirectional Mapping Annotation Example tutorial shows you how to use Hibernate Many-To-One Bidirectional mapping using annotation based configuration. The Many-To-One Bidirectional mapping said that one table has a foreign key column that referring the primary key of associated table.
We are taking an example of Student and ClassRoom relationship. This relationship said that a student registers one ClassRoom and one ClassRoom has many students.
Other interesting posts you may like
Create required 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 |
create table CLASS_ROOM ( class_room_id BIGINT NOT NULL AUTO_INCREMENT, name VARCHAR(30) NOT NULL, PRIMARY KEY (CLASS_ROOM_ID) ); create table STUDENT ( id INT(11) NOT NULL AUTO_INCREMENT, name VARCHAR(100) NOT NULL, entering_date DATE NOT NULL, nationality TEXT NOT NULL, code VARCHAR(30) NOT NULL, class_room_id INT(11) NOT NULL, PRIMARY KEY (id), CONSTRAINT student_classroom FOREIGN KEY (class_room_id) REFERENCES CLASS_ROOM (class_room_id) ON UPDATE CASCADE ON DELETE CASCADE ); |
Noticed that STUDENT table contains a foreign key (here is class_room_id field) referring to a primary key (here is id field) of CLASS_ROOM table.
Create project directory structure
In this Hibernate Many to One Bidirectional Mapping Annotation Example , we will create java project with final directory 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>ManyToOneBidirectionalMappingExample</artifactId> <version>1.0.0</version> <packaging>jar</packaging> <name>ManyToOneBidirectionalMappingExample</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 classes
Model class Student and ClassRoom are simple POJO class. Here we are using class Student and ClassRoom 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 |
package com.javabycode.hibernate.model; import java.io.Serializable; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; 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; @ManyToOne(optional = false) @JoinColumn(name = "CLASS_ROOM_ID") private ClassRoom classRoom; 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 setClassRoom(ClassRoom classRoom) { this.classRoom = classRoom; } public ClassRoom getClassRoom() { return classRoom; } @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.toString() + ", nationality=" + nationality + ", code=" + code + "]"; } } |
ClassRoom 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 |
package com.javabycode.hibernate.model; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; @Entity @Table(name = "CLASS_ROOM") public class ClassRoom { @Id @GeneratedValue @Column(name = "CLASS_ROOM_ID") private long id; @Column(name = "NAME") private String name; @OneToMany(mappedBy = "classRoom", cascade = CascadeType.ALL) private List students; public ClassRoom() { } public ClassRoom(String name) { this.name = name; } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void setStudents(List students) { this.students = students; } public List getStudents() { return students; } @Override public String toString() { return "ClassRoom [id=" + id + ", name=" + name + "]"; } } |
Let’s dig deeper:
1 2 |
@OneToMany(mappedBy = "classRoom", cascade = CascadeType.ALL) private List<Student> students; |
@OneToMany on students property says that one ClassRoom can have multiple students. From these students we can navigate from ClassRoom to Student.
The mappedBy attribute indicates that it’s the inverse side of relationship. It means that multiple students are belong to one classRoom.
Thank to the cascade attribute, all Student objects will be persisted/updated/deleted automatically on subsequent persist/update/delete on ClassRoom object.
On Student entity side:
1 2 3 |
@ManyToOne(optional = false) @JoinColumn(name = "CLASS_ROOM_ID") private ClassRoom classRoom; |
@ManyToOne annotation says that many Students refer to one ClassRoom and the attribute optional=false means this relationship becomes mandatory (no student row can be saved without a classRoom reference).
@JoinColumn annotation indicates that column CLASS_ROOM_ID in Student table will refer to primary key of the CLASS_ROOM table.
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 |
<!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.ClassRoom"/> </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 a program to demonstrate
We will create main class to demonstrate this Hibernate Many to One Bidirectional Mapping Annotation Example.
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 |
package com.javabycode.hibernate; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.List; import org.hibernate.Session; import com.javabycode.hibernate.model.Student; import com.javabycode.hibernate.model.ClassRoom; public class HibernateExample { @SuppressWarnings("unchecked") public static void main(String[] args) { Calendar cal = GregorianCalendar.getInstance(); Student student1 = new Student("David Pham", cal.getTime(), "USA", "1234566"); Student student2 = new Student("Bill Murray", cal.getTime(), "USA", "1234567"); Student student3 = new Student("Steve Carell", cal.getTime(), "USA", "1234568"); ClassRoom classRoom = new ClassRoom("Math"); List<Student> allStudents = new ArrayList<Student>(); student1.setClassRoom(classRoom); student2.setClassRoom(classRoom); student3.setClassRoom(classRoom); allStudents.add(student1); allStudents.add(student2); allStudents.add(student3); classRoom.setStudents(allStudents); Session session = HibernateUtil.getSessionFactory().openSession(); session.beginTransaction(); session.persist(classRoom); session.getTransaction().commit(); List<Student> students = (List<Student>) session.createQuery("from Student ").list(); for (Student s : students) { System.out.println("Student Details : " + s); System.out.println("Student ClassRoom Details: " + s.getClassRoom()); } session.close(); } } |
In the above code, you can see that we have updated only classRoom explicitly. But thank to the cascade attribute that is set to all on students property of ClassRoom, so that all student objects will be saved on persisting ClassRoom object.
Run main class and we get the output like below:
1 2 3 4 5 6 |
Student Details : Student [id=40, name=David Pham, enteringDate=Sat Oct 08 11:11:23 ICT 2016, nationality=USA, code=1234566] Student ClassRoom Details: ClassRoom [id=18, name=Math] Student Details : Student [id=41, name=Bill Murray, enteringDate=Sat Oct 08 11:11:23 ICT 2016, nationality=USA, code=1234567] Student ClassRoom Details: ClassRoom [id=18, name=Math] Student Details : Student [id=42, name=Steve Carell, enteringDate=Sat Oct 08 11:11:23 ICT 2016, nationality=USA, code=1234568] Student ClassRoom Details: ClassRoom [id=18, name=Math] |
That’s it on the Hibernate Many to One Bidirectional Mapping Annotation Example tutorial.
Download complete source code, please hit link below
ManyToOneBidirectionalMappingExample.zip (277 downloads)
It’s not my first time to go to see this website, i am browsing this web site dailly and obtain nice data from here all
the time.
Seriously….this is a important web site.
Thanks really valuable. Will share site with my friends.
Thanks for sharing your thoughts about Hibernate Many to One Bidirectional Mapping Annotation Example.
Regards
Everything is very open with a really clear description of the issues.
It was definitely informative. Your website is extremely helpful.
Thanks for sharing!
I am truly pleased to glance at this web site posts which includes lots of helpful information, thanks for providing these data.
We are a bunch of volunteers and starting a brand new scheme in our community.
Your web site provided us with useful information to work on. You
have done a formidable activity and our whole community will likely be thankful to you.