SpringBoot JPA @OneToMany Mapping : Fetch data from tables

SpringBoot JPA @OneToMany Mapping as name says we will see one to many mapping in SpringBoot and JPA.

First see the ER Diagram

SpringBoot JPA @OneToMany Mapping ER Diagram

Following is the Entity Relationship Diagram for user, user_mails and user_mobiles table.

One user can have multiple mail ids.

So this is a one to many relation.

similarly one user can have multiple mobile numbers.

This is also one to many mapping.

user’s id in user table is

Fig: Entity Relationship Diagram

Tools/Technology used

  1. Spring Boot 2.2
  2. JPA
  3. Eclipse IDE
  4. MySQL Database

SpringBoot JPA @OneToMany Mapping Directory Structure

SpringBoot  JPA @OneToMany Mapping Project Directory Structure
Fig: Project Directory Structure

To build project we used maven and included

  1. spring-boot-starter-web
  2. spring-boot-starter-data-jpa
  3. mysql-connector-java

You can also use spring Initializr to generate POM.xml

POM.xml



	4.0.0
	
		org.springframework.boot
		spring-boot-starter-parent
		2.7.2
		 
	
	com.ebhor
	mvc
	0.0.1-SNAPSHOT
	war
	Spring Crud
	Spring CRUD Example
	
		1.8
	
	
		
			org.springframework.boot
			spring-boot-starter-web
		
		
			org.springframework.boot
			spring-boot-starter-data-jpa
		
		
			org.springframework.boot
			spring-boot-starter-tomcat
			provided
		
		
			org.springframework.boot
			spring-boot-starter-test
			test
		
		
			mysql
			mysql-connector-java
			runtime
		
		
	
	
		
			
				org.springframework.boot
				spring-boot-maven-plugin
			
		
	

Application.properties file configuration

MySQL database is used.

Configuration with MySQL is as specified below

spring.datasource.url=jdbc:mysql://localhost:3306/ebhor
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect

Entities

We have created three entity files User, UserMail and UserMobile.

Tables and columns are mapped in entity file.

User.java

To access multiple mail and mobile numbers user is mapped with UserMail and UserMobile entities.

@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set userMails = new HashSet(0);

@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set userMobiles = new HashSet(0);

@oneToMany mapping is used and few parameters are also used.

  1. mappedBy- a property name in userMails. Based on this property matching oneToMany mapping will be performed.
  2. cascade- Transactions that are performing on table will also perform on mapped table or not.
  3. fetch – specifies when to access mapped data from join table
package com.ebhor.crud.entity;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
@Entity
@Table(name = "user")
public class User {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "id")
	private int id;
	@Column(name = "name", nullable = false)
	private String name;
	@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
	private Set userMails = new HashSet(0);
	@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
	private Set userMobiles = new HashSet(0);
	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 Set getUserMails() {
		return userMails;
	}
	public void setUserMails(Set userMails) {
		this.userMails = userMails;
	}
	public User(int id, String name, Set userMails) {
		super();
		this.id = id;
		this.name = name;
		this.userMails = userMails;
	}
	public User() {
		super();
	}
	public Set getUserMobiles() {
		return userMobiles;
	}
	public void setUserMobiles(Set userMobiles) {
		this.userMobiles = userMobiles;
	}
}

UserMail.java

@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "user_id")
@JsonIgnore
private User user;

Here User Object is mapped as Many to one.

The @JoinColumn specified based on which (user_mail) column it will perform join and fetch data.

@JsonIgnore- This will ignored the json result and prevent the loop.

package com.ebhor.crud.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonIgnore;

@Entity
@Table(name = "user_mails")
public class UserMail {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private int id;

	@Column(name = "email", nullable = false)
	private String email;

	@ManyToOne(fetch = FetchType.LAZY, optional = false)
	@JoinColumn(name = "user_id")
	@JsonIgnore
	private User user;

	public UserMail() {
		super();
	}

	public UserMail(int id, String email, User user) {
		super();
		this.id = id;
		this.email = email;
		this.user = user;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

}

UserMobiles

package com.ebhor.crud.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;

import com.fasterxml.jackson.annotation.JsonIgnore;

@Entity
@Table(name = "user_mobiles")
public class UserMobile {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private int id;

	@Column(name = "mobile_no", nullable = false)
	private String mobileNo;

	@ManyToOne(fetch = FetchType.LAZY, optional = false)
	@JoinColumn(name = "user_id")
	@JsonIgnore
	private User user;

	public UserMobile() {

	}

	public UserMobile(int id, String mobileNo, User user) {
		super();
		this.id = id;
		this.mobileNo = mobileNo;
		this.user = user;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getMobileNo() {
		return mobileNo;
	}

	public void setMobileNo(String mobileNo) {
		this.mobileNo = mobileNo;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

}

UserDAO.java

UserDAO is responsible for fetching data from database.

package com.ebhor.crud.dao;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.ebhor.crud.entity.User;
@Repository
public interface UserDAO extends CrudRepository{
}

UserService.java

package com.ebhor.crud.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ebhor.crud.dao.UserDAO;
import com.ebhor.crud.entity.User;
@Service
public class UserService {
	@Autowired
	UserDAO dao;
	public Iterable getUsers(){
		return dao.findAll();
	}
}

UserController.java

Here we have used RestController to show data on index position

package com.ebhor.crud.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ebhor.crud.entity.User;
import com.ebhor.crud.service.UserService;
@RestController
public class UserController {
	@Autowired
	UserService service;
	
	@GetMapping("/")
	public Iterable users(){
		return service.getUsers();
	}
}

Result

On running above project we will get following data.

Result of @OneToMany Mapping
Fig: Result of @OneToMany Mapping

Read More

Angular Spring Boot Showing Data In Table