jpa

JPA Relationship Annotations Example

Here we will look into the JPA Relationship Annotations. This article takes you through the relationships between Entities. Generally the relations are more effective between tables in the database and as We already know that in RDBMS every entity(table) must be related to other entities to become meaningful. Here the entity classes are treated as relational tables (concept of JPA).
 
 
 
 
 

 
The relationships between Entity classes are as follows:

@ManyToOne Relation
@OneToMany Relation
@OneToOne Relation
@ManyToMany Relation

We will look into each of them.

1. The Database

For the sake of simplicity we will use the Oracle Database. We will create separate schema with ER-Diagram for each of the topics (relationship types) to help you understand.

2. Many to One Relation

2.1 The Database Schema & ER Diagram

A many to one relationship can occur when many entities of the source table is related to one entity of the target table. For example many employee can work in a single department.

2.1.1 The ER Diagram

Employee - Project ER Diagram
Employee – Project ER Diagram

2.1.2 The Tables

department1.sql

create table department(did number(3) primary key, dname varchar2(25));

employee1.sql

create table employee(eid number(3) primary key, ename varchar2(25), salary number(7), job_id number(3), did number(3) references department(did) on delete set null);

2.2 The Java Code

2.2.1 Unidirectional Single Valued Mapping

A unidirectional many to one relationships in JPA2 is defined by simply annotating the attribute in the Source entity that refers to the target entity with @ManyToOne annotation. Have a look to the figure below, The important thing to notice in the figure is that the arrow head points from Employee to Department and not the other way round.

Employee – Department ER Diagram
Employee – Department ER Diagram

The example below shows the Employee entity that has a unidirectional ManyToOne association with the Department entity.

Department.java

package com.javacodegeeks.examples.rivu.jpa.entity;

import java.io.Serializable;

import javax.persistence.*;

/**
 * Entity implementation class for Entity: Department
 *
 */
@Entity

public class Department implements Serializable {

	
	private static final long serialVersionUID = 1L;
	
	@Id
	 @GeneratedValue(strategy= GenerationType.AUTO)
	 private int did;
	private String dname;
	

	public Department() {
		super();
	}


	public Department(int did, String dname) {
		super();
		this.did = did;
		this.dname = dname;
	}


	public int getDid() {
		return did;
	}


	public void setDid(int did) {
		this.did = did;
	}


	public String getDname() {
		return dname;
	}


	public void setDname(String dname) {
		this.dname = dname;
	}
	
	
   
}

Employee.java

package com.javacodegeeks.examples.rivu.jpa.entity;

import java.io.Serializable;

import javax.persistence.*;

/**
 * Entity implementation class for Entity: Employee
 *
 */
@Entity

public class Employee implements Serializable {

	
	private static final long serialVersionUID = 1L;
	
	@Id
	 @GeneratedValue(strategy= GenerationType.AUTO)
	 private int eid;
	private String ename;
	private double salary;
	private int job_id;
	
	@ManyToOne
    @JoinColumn(name="did")
    private Department department;

	public Employee() {
		super();
	}

	public int getEid() {
		return eid;
	}

	public void setEid(int eid) {
		this.eid = eid;
	}

	public String getEname() {
		return ename;
	}

	public void setEname(String ename) {
		this.ename = ename;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	public int getJob_id() {
		return job_id;
	}

	public void setJob_id(int job_id) {
		this.job_id = job_id;
	}

	public Department getDepartment() {
		return department;
	}

	public void setDepartment(Department department) {
		this.department = department;
	}

	public Employee(int eid, String ename, double salary, int job_id,
			Department department) {
		super();
		this.eid = eid;
		this.ename = ename;
		this.salary = salary;
		this.job_id = job_id;
		this.department = department;
	}
	
	
   
}

ManytoOneService.java

package com.javacodegeeks.examples.rivu.jpa.service;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import com.javacodegeeks.examples.rivu.jpa.entity.Employee;
import com.javacodegeeks.examples.rivu.jpa.entity.Department;

public class ManytoOneService {

	public static void main(String[] args) {
		
		
		EntityManagerFactory emfactory = Persistence.createEntityManagerFactory( "RivuChk_JPA" );
	   	EntityManager entitymanager = emfactory.createEntityManager( );
	   	entitymanager.getTransaction( ).begin( );
	   	
	   	Department department = entitymanager.find(Department.class, 1);

	   	System.out.println("Department: "+department.getDname());
	   	
		entitymanager.getTransaction( ).commit( );
		entitymanager.getTransaction( ).begin( );
		
		entitymanager.persist(department);
		
		Employee employee = new Employee();
		employee.setEname("Rivu");
		employee.setSalary(25000);
		employee.setJob_id(1);
		employee.setDepartment(department);
		
		entitymanager.persist(employee);
		
		int employeeId = employee.getEid();
		
		entitymanager.getTransaction().commit();
		
		entitymanager.getTransaction().begin();
		
		Employee dbEmployee =entitymanager.find(Employee.class, employeeId);
		System.out.println("Employee " + dbEmployee);
		
		entitymanager.getTransaction().commit();
		
		entitymanager.close();
		emfactory.close();
	   	
	   	
	}

}

2.3 Output

[EL Fine]: sql: 2015-04-12 22:19:06.071--ServerSession(2059904228)--Connection(2095602418)--Thread(Thread[main,5,main])--SELECT DID, DNAME FROM DEPARTMENT WHERE (DID = ?)
	bind => [1]
Department: IT Software

[EL Fine]: sql: 2015-04-12 22:19:06.088--ClientSession(1469235340)--Connection(2095602418)--Thread(Thread[main,5,main])--INSERT INTO EMPLOYEE (EID, ENAME, JOB_ID, SALARY, did) VALUES (?, ?, ?, ?, ?)
	bind => [601, Rivu, 1, 25000.0, 1]
Employee [ id=601 ename=Rivu salary=25000.0 jobid=1 Department=[ id=1 dname=IT Software]]

3. One to Many Relation

3.1 The Database Schema & ER Diagram

A one to many relationship can occur when one entity of the source table is related to many entities of the target table. For example one employee can work in multiple projects.

Its a vice versa of ManytoOne relation. It depends on which side of the relationship the entity is present on.

3.1.1 The ER Diagram

Employee - Project ER Diagram
Employee – Project ER Diagram

3.1.2 The Tables

projects1.sql

create table projects(p_id number(3) primary key, title varchar2(25), eid number(3) references employee(eid) on delete set null);

employee1.sql

create table employee(eid number(3) primary key, ename varchar2(25), salary number(7), job_id number(3), did number(3) references department(did) on delete set null);

3.2 The Java Code

The example below shows the Employee entity that has a Bidirectional OneToMany association with the Projects entity.

Projects.java

package com.javacodegeeks.examples.rivu.jpa.entity;

import java.io.Serializable;

import javax.persistence.*;

/**
 * Entity implementation class for Entity: Department
 *
 */
@Entity

public class Projects implements Serializable {

	
	private static final long serialVersionUID = 1L;
	
	@Id
	 @GeneratedValue(strategy= GenerationType.AUTO)
	 private int p_id;
	private String title;
	
	@ManyToOne
    @JoinColumn(name="eid")
    private Employee employee;
	
	public Projects() {
		super();
	}

	public Projects(int p_id, String title, Employee employee) {
		super();
		this.p_id = p_id;
		this.title = title;
		this.employee = employee;
	}

	public int getP_id() {
		return p_id;
	}

	public void setP_id(int p_id) {
		this.p_id = p_id;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public Employee getEmployee() {
		return employee;
	}

	public void setEmployee(Employee employee) {
		this.employee = employee;
	}

	@Override
	public String toString() {
		
		return "[Project ID="+p_id+" Title="+title+" ]";
	}
	
		
	
}

Employee.java Modified

package com.javacodegeeks.examples.rivu.jpa.entity;

import java.io.Serializable;
import java.util.List;

import javax.persistence.*;

/**
 * Entity implementation class for Entity: Employee
 *
 */
@Entity

public class Employee implements Serializable {

	
	private static final long serialVersionUID = 1L;
	
	@Id
	 @GeneratedValue(strategy= GenerationType.AUTO)
	 private int eid;
	private String ename;
	private double salary;
	private int job_id;
	
	@ManyToOne
    @JoinColumn(name="did")
    private Department department;
	
	@OneToMany
    @JoinColumn(name="eid")
    private List projects;
	

	public Employee() {
		super();
	}

	public int getEid() {
		return eid;
	}

	public void setEid(int eid) {
		this.eid = eid;
	}

	public String getEname() {
		return ename;
	}

	public void setEname(String ename) {
		this.ename = ename;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	public int getJob_id() {
		return job_id;
	}

	public void setJob_id(int job_id) {
		this.job_id = job_id;
	}

	public Department getDepartment() {
		return department;
	}

	public void setDepartment(Department department) {
		this.department = department;
	}

	public Employee(int eid, String ename, double salary, int job_id,
			Department department) {
		super();
		this.eid = eid;
		this.ename = ename;
		this.salary = salary;
		this.job_id = job_id;
		this.department = department;
	}
	

	public List getProjects() {
		return projects;
	}

	public void setProjects(List projects) {
		this.projects = projects;
	}

	@Override
	public String toString() {
		
		return "[ id="+eid+" ename="+ename+" salary="+salary+" jobid="+job_id+" Department="+department+"]";
	}
	
	
	
	
   
}

OnetoManyService.java

package com.javacodegeeks.examples.rivu.jpa.service;

import java.util.Iterator;
import java.util.List;
import java.util.Scanner;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import com.javacodegeeks.examples.rivu.jpa.entity.Employee;
import com.javacodegeeks.examples.rivu.jpa.entity.Department;
import com.javacodegeeks.examples.rivu.jpa.entity.Projects;

public class OnetoManyService {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		Scanner sc=new Scanner(System.in);
		
		EntityManagerFactory emfactory = Persistence.createEntityManagerFactory( "RivuChk_JPA" );
	   	EntityManager entitymanager = emfactory.createEntityManager( );
	   	entitymanager.getTransaction( ).begin( );
	   	
	   	System.out.println("Enter Employee ID");
	   	
	   	int eid=sc.nextInt();
	   	
	   	Employee emp = entitymanager.find(Employee.class, eid);

	   	System.out.println("Employee: "+emp.toString());
	   	List projects=emp.getProjects();
	   	
	   	Iterator ps=projects.iterator();
	   	
	   	int count=0;
	   	
	   	while(ps.hasNext())
	   	{
	   		System.out.println("Project "+(++count)+" : "+ps.next().toString());
	   	}
	   		
	   	
		entitymanager.getTransaction( ).commit( );
		
		
		entitymanager.close();
		emfactory.close();
	   	
	   	
	}

}

3.3 Output

[EL Fine]: sql: 2015-05-22 21:48:01.564--ServerSession(853119666)--Connection(1177903557)--Thread(Thread[main,5,main])--SELECT * FROM SEQUENCE WHERE SEQ_NAME = SEQ_GEN
Enter Employee ID
401
[EL Fine]: sql: 2015-05-22 21:48:04.139--ServerSession(853119666)--Connection(1177903557)--Thread(Thread[main,5,main])--SELECT EID, ENAME, JOB_ID, SALARY, did FROM EMPLOYEE WHERE (EID = ?)
	bind => [401]
[EL Fine]: sql: 2015-05-22 21:48:04.146--ServerSession(853119666)--Connection(1177903557)--Thread(Thread[main,5,main])--SELECT DID, DNAME FROM DEPARTMENT WHERE (DID = ?)
	bind => [1]
Employee: [ id=401 ename=Rivu salary=20000.0 jobid=1 Department=[ id=1 dname=HR]]
[EL Fine]: sql: 2015-05-22 21:48:04.157--ServerSession(853119666)--Connection(1177903557)--Thread(Thread[main,5,main])--SELECT P_ID, TITLE, eid FROM PROJECTS WHERE (eid = ?)
	bind => [401]
Project 1 : [Project ID=2 Title=www.vracommunity.com ]
Project 2 : [Project ID=1 Title=Android App Project ]

3.4 Explanation

In Projects.java We used @ManyToOne notation to map Employee entity with Projects entity in ManyToOne relation.
We modified the Employee.java, used @OneToMany for Bi-directional mapping with the Project class.

Thus whenever we select a record from the employee table, the related records from the projects table is also selected automatically.

4. One to One Relation

4.1 The Database Schema & ER Diagram

A one to one relationship can occur when one entity of the source table is related to only one entity of the target table. For example one employee can can do a single job.

4.1.1 The ER Diagram

Employee - Job ER Diagram
Employee – Job ER Diagram

4.1.2 The Tables

job1.sql

create table job(job_id number(3) primary key, designation varchar2(25));

We have to make a small alteration to the employee table

employee2.sql

alter table employee modify(job_id number(3) references job(job_id));

4.2 The Java Code

The example below shows the Employee entity that has a bidirectional OneToOne association with the Job entity.

Job.java

package com.javacodegeeks.examples.rivu.jpa.entity;

import java.io.Serializable;

import javax.persistence.*;

/**
 * Entity implementation class for Entity: Job
 *
 */
@Entity

public class Job implements Serializable {

	
	private static final long serialVersionUID = 1L;
	
	@Id
	 @GeneratedValue(strategy= GenerationType.AUTO)
	 private int job_id;
	private String designation;
	

	@OneToOne(mappedBy="job")
    private Employee employee;

	public Job() {
		super();
	}

	public Job(int job_id, String designation) {
		super();
		this.job_id = job_id;
		this.designation = designation;
	}

	public int getJob_id() {
		return job_id;
	}

	public void setJob_id(int job_id) {
		this.job_id = job_id;
	}

	public String getDesignation() {
		return designation;
	}

	public void setDesignation(String designation) {
		this.designation = designation;
	}

	public Employee getEmployee() {
		return employee;
	}

	public void setEmployee(Employee employee) {
		this.employee = employee;
	}

	@Override
	public String toString() {
		
		return "[ job_id="+job_id+" Designation="+designation+" ]";
	}
	
	
   
}

We have to modify the Employee.java again, to change the int job_id; to Job job;. You can easily get the changes as old codes are commented out.

Employee.java

package com.javacodegeeks.examples.rivu.jpa.entity;

import java.io.Serializable;
import java.util.List;

import javax.persistence.*;

/**
 * Entity implementation class for Entity: Employee
 *
 */
@Entity

public class Employee implements Serializable {

	
	private static final long serialVersionUID = 1L;
	
	@Id
	 @GeneratedValue(strategy= GenerationType.AUTO)
	 private int eid;
	private String ename;
	private double salary;
	//private int job_id;
	
	@ManyToOne
    @JoinColumn(name="did")
    private Department department;
	
	@OneToOne
    @JoinColumn(name="job_id")
    private Job job;
	
	@OneToMany
    @JoinColumn(name="eid")
    private List projects;
	

	public Employee() {
		super();
	}

	public int getEid() {
		return eid;
	}

	public void setEid(int eid) {
		this.eid = eid;
	}

	public String getEname() {
		return ename;
	}

	public void setEname(String ename) {
		this.ename = ename;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}
/*
	public int getJob_id() {
		return job_id;
	}

	public void setJob_id(int job_id) {
		this.job_id = job_id;
	}
*/

	public Job getJob() {
		return job;
	}

	public void setJob(Job job) {
		this.job = job;
	}
	
	public Department getDepartment() {
		return department;
	}


	public void setDepartment(Department department) {
		this.department = department;
	}

	public Employee(int eid, String ename, double salary, Job job,
			Department department) {
		super();
		this.eid = eid;
		this.ename = ename;
		this.salary = salary;
		this.job = job;
		this.department = department;
	}
	

	public List getProjects() {
		return projects;
	}

	public void setProjects(List projects) {
		this.projects = projects;
	}

	@Override
	public String toString() {
		
		return "[ id="+eid+" ename="+ename+" salary="+salary+" job="+job.toString()+" Department="+department+"]";
	}
	
	
	
	
   
}

OnetoOneService.java

package com.javacodegeeks.examples.rivu.jpa.service;

import java.util.Iterator;
import java.util.List;
import java.util.Scanner;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import com.javacodegeeks.examples.rivu.jpa.entity.Employee;
import com.javacodegeeks.examples.rivu.jpa.entity.Department;
import com.javacodegeeks.examples.rivu.jpa.entity.Job;
import com.javacodegeeks.examples.rivu.jpa.entity.Projects;

public class OnetoOneService {

	public static void main(String[] args) {
		
		
		Scanner sc=new Scanner(System.in);
		
		EntityManagerFactory emfactory = Persistence.createEntityManagerFactory( "RivuChk_JPA" );
	   	EntityManager entitymanager = emfactory.createEntityManager( );
	   	entitymanager.getTransaction( ).begin( );
	   	
	   	System.out.println("Enter Job ID");
	   	
	   	int jid=sc.nextInt();
	   	
	   	Job job = entitymanager.find(Job.class, jid);

	   	System.out.println("Job: "+job.toString());
	   	
	   	
	   Employee emp=job.getEmployee();
	   
	   System.out.println("Employee: "+emp.toString());
	   	
		entitymanager.getTransaction( ).commit( );
		
		
		entitymanager.close();
		emfactory.close();
	   	
	   	
	}

}

4.3 Output

[EL Fine]: sql: 2015-05-23 16:20:56.656--ServerSession(559670971)--Connection(879292014)--Thread(Thread[main,5,main])--SELECT * FROM SEQUENCE WHERE SEQ_NAME = SEQ_GEN
Enter Job ID
1
[EL Fine]: sql: 2015-05-23 16:20:59.684--ServerSession(559670971)--Connection(879292014)--Thread(Thread[main,5,main])--SELECT JOB_ID, DESIGNATION FROM JOB WHERE (JOB_ID = ?)
	bind => [1]
[EL Fine]: sql: 2015-05-23 16:20:59.726--ServerSession(559670971)--Connection(879292014)--Thread(Thread[main,5,main])--SELECT EID, ENAME, SALARY, did, job_id FROM EMPLOYEE WHERE (job_id = ?)
	bind => [1]
[EL Fine]: sql: 2015-05-23 16:20:59.745--ServerSession(559670971)--Connection(879292014)--Thread(Thread[main,5,main])--SELECT DID, DNAME FROM DEPARTMENT WHERE (DID = ?)
	bind => [1]
Job: [ job_id=1 Designation=Software Engineer ]
Employee: [ id=101 ename=Illias salary=20000.0 job=[ job_id=1 Designation=Software Engineer ] Department=[ id=1 dname=HR]]

5. Download

This was an example of JPA Relationship Annotations.

Download
You can download the full source code of this example here:
JPA_Relationship_Annotation

Rivu Chakraborty

Rivu Chakraborty is a Google Certified Android Developer, Sr. Tech Member of Institute of Engineers (India), he also have certifications on Scrum. He is also an author of multiple books on Kotlin, Reactive Programming, Functional Programming and Android Development, published by renowned publication houses. Having total 5+ years of experience he is presently working as a Sr. Software Engineer (Android) at Indus Net Technologies Pvt. Ltd. Rivu Chakraborty considers himself a Kotlin and Android enthusiast and a Kotlin evangelist. He has been using Kotlin since December 2015, so he has around 2 years' experience in Kotlin. As part of his mission to expand the use and knowledge of the Kotlin Language as much as possible, he created the KotlinKolkata User Group, one of the most active Kotlin user groups throughout the world and he is a Founder Organizer of KotlinKolkata. He is also an active member of GDG Kolkata and gives talks at GDG Kolkata Meetups.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button