Annotation @ManyToOne in JPA is used to express multiple-to-one relationships between two tables in a database. There are many records in table A related to a record in table B. For example: many different students may have the same class. In this tutorial, we will work together to find out more about this annotation.
To illustrate, I will take the relationship between students and classrooms as examples. The database structure of these two tables is as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
CREATE TABLE `clazz` ( `id` int(11) NOT NULL, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `student` ( `id` int(11) NOT NULL, `name` varchar(255) DEFAULT NULL, `clazz_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`), FOREIGN KEY (`clazz_id`) REFERENCES `clazz` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
OK …
First, I will create a project to work with this example:
with Hibernate dependency as follows:
1 2 3 4 5 |
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.2.11.Final</version> </dependency> |
Because in this example, I work with MySQL so I will also add dependency for MySQL Driver:
1 2 3 4 5 |
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>6.0.6</version> </dependency> |
Next, I will create two entities that represent 2 tables clazz and student.
The content of the Clazz entity is as follows:
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 |
package com.huongdanjava.jpamanytoone; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table public class Clazz { @Id @GeneratedValue private Integer id; @Column private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } |
and entity Student:
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 |
package com.huongdanjava.jpamanytoone; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table public class Student { @Id @GeneratedValue private Integer id; @Column private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } |
Now, we will use the @ManyToOne annotation to show the many – one relationship between the Student and Clazz entity.
Because, this is a multiple-view relationship from a student object, so we’ll put the @ManyToOne annotation in the Student entity.
I will add a new field in the Student entity to use with the @ManyToOne annotation as follows:
1 2 3 4 5 6 7 8 9 10 |
@ManyToOne private Clazz clazz; public Clazz getClazz() { return clazz; } public void setClazz(Clazz clazz) { this.clazz = clazz; } |
Here, I only use one annotation @ManyToOne without any other configuration. Therefore, the default configuration for this annotation will be used. I will tell you what these default values are?
As you know, in any database, the concept of relationship means that a table in this database has a link to another table in the database. And when a column in this table references to a primary key of the other table, we call this is a foreign key column.
In JPA, if you only use the @ManyToOne annotation, the name of the foreign key column will be defined with a default name. This default name will be based on two entities. It is the name of the variable that defines the relationship between the two entities with the annotation @ManyToOne. In our example, the clazz variable in the Student entity, followed by the underscore and finally the name of the variable acting as primary key in the other entity. In this example, it is the id variable in the Clazz entity.
Thus, in our example, this foreign key column will be named clazz_id in the student table.
In case, the foreign key column in the student table does not match the default name defined by JPA, then you need to use another annotation named @JoinColumn to define the foreign key column. In this annotation, we have an attribute named name to define the name of the foreign key column. In our example, we can add @JoinColumn annotation as follows:
1 2 3 |
@ManyToOne @JoinColumn(name = "clazz_id") private Clazz clazz; |
Currently, in the student table we have defined the foreign key column clazz_id is the same as the default name, so now we can use the two entities above.
To work with JPA, we need to add a configuration file for JPA, persistence.xml, located in the /src/main/resources/META-INF directory of the project.
with the following content:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence_2_1.xsd"> <persistence-unit name="jpaexample" transaction-type="RESOURCE_LOCAL"> <class>com.huongdanjava.jpamanytoone.Clazz</class> <class>com.huongdanjava.jpamanytoone.Student</class> <exclude-unlisted-classes>true</exclude-unlisted-classes> <properties> <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" /> <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/jpaexample" /> <property name="javax.persistence.jdbc.user" value="root" /> <property name="javax.persistence.jdbc.password" value="123456" /> <property name="javax.persistence.schema-generation.database.action" value="drop-and-create" /> <property name="hibernate.format_sql" value="true" /> <property name="hibernate.use_sql_comments" value="true" /> </properties> </persistence-unit> </persistence> |
Now, I will write code to add a class with two students as follows:
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 |
package com.huongdanjava.jpaexample; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.persistence.Persistence; public class Example { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpaexample"); EntityManager em = emf.createEntityManager(); EntityTransaction transaction = em.getTransaction(); transaction.begin(); Clazz clazz = new Clazz(); clazz.setName("Class A"); em.persist(clazz); Student student1 = new Student(); student1.setName("Khanh"); student1.setClazz(clazz); em.persist(student1); Student student2 = new Student(); student2.setName("Phung"); student2.setClazz(clazz); em.persist(student2); transaction.commit(); em.close(); emf.close(); } } |
Result:
As you can see, when you insert data into the database, the id of class A is automatically set to the value of the clazz_id column in the student table.