Spring Data JPA One to Many Mapping Example

Mapping is one of the important topics when you are establishing a relationship between two or more tables. Here, we will learn how to map one-to-many mapping using spring data JPA in the Spring boot Application.

Note: In case you want to know more about Spring Data JPA check this article https://codedec.com/tutorials/spring-data-jpa-in-spring-boot-with-example/

What is a One-to-Many Relationship?

The mapping between two entities in which one entity is related to a second entity with the One to Many relationships and the second entity is related to a first entity with the many to one relationship.

Example: Here, we can have lots of examples like one book have multiple pages, one movie has multiple characters, one category has multiple products.

Following is the  database representation of @onetoMany Relationship

Here, the parent table is Mobile which has a primary key id and the child table is the app that has a foreign key mobile_id reference to Mobile Table.

Let us create the OneToMany Example using Spring Data JPA in Spring Boot.

Spring Data JPA One to Many Mapping Example

Step 1: Open IDE STS- Spring Tool Suite

Step 2: Go to File > Spring Starter Project.

Step 3: Now, fill all the fields as shown below and click Next.

Step 4: Now, Add the dependencies of spring data JPA, MYSQL Driver, Lombok, and spring web.

Now, wait for some time and your project structure will be ready. Go to the pom.xml file and you will see the following dependencies will be added automatically.

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <scope>runtime</scope>
</dependency>

Create a Database in MYSQL

create database one_to_manyjpa;

Configure application. properties file

This is the file provided by spring boot to configure JDBC URL, username, password, and driver class name. Also, configure JPA-related information.

spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://localhost:3306/one_to_manyJPA
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name =com.mysql.jdbc.Driver
spring.jpa.show-sql= true
## Hibernate Properties
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
#To format SQL queries generated by Hibernate
spring.jpa.properties.hibernate.format_sql=true

#change port number
server.port=8888
  • spring.jpa.hibernate.ddl-auto is set to update so that whatever changes we will do will be reflected in the schema.
  • spring.datasource.url is used to set the URL of the MYSQL DB.
  • spring.datasource.username is used to set the username and spring. datasource. password is used to set the password.
  • spring.datasource.driver-class-name is used to set the driver class name.
  • spring.jpa.show-sql is set to true to show SQL generated by the Hibernate.
  • spring.jpa.properties.hibernate.dialect is used to generate better SQL for the chosen database.
  • spring.jpa.properties.hibernate.format_sql is set to true to format SQL queries.
  • server.port is set to 8888.

Create an Entity Class

Create two Entity Mobile and App that will have an OneToMany relationship.

Mobile.java

package com.abc.example.mapping.model;

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.OneToMany;
import javax.persistence.Table;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@Entity
@Table(name = "mobile")
@Setter
@Getter
@RequiredArgsConstructor
@AllArgsConstructor

public class Mobile {

 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private long id;
 @Column(name = "mobile_name",length = 255)
 private String mobileName;
 @Column(name = "mobile_company", length = 255)
 private String mobileCompany;
 @OneToMany(mappedBy = "mobile",cascade = CascadeType.ALL,fetch = FetchType.EAGER)
 private Set<Apps> apps;
 @Override
 public String toString() {
  return "Mobile [id=" + id + ", mobileName=" + mobileName + ", mobileCompany=" + mobileCompany + ", apps=" + apps
    + "]";
 }
}

Apps.java

package com.abc.example.mapping.model;

import java.util.Set;

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;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@Entity
@Table(name = "app")
@Setter
@Getter
@RequiredArgsConstructor
@AllArgsConstructor

public class Apps {

 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private long id;
 @Column(name = "app_name",length = 255)
 private String appName;
 @Column(name = "app_size",length = 255)
 private long appSize;
 @ManyToOne
 @JoinColumn(name = "mobile_id",nullable = false)
 private Mobile mobile;
 @Override
 public String toString() {
  return "Apps [id=" + id + ", appName=" + appName + ", appSize=" + appSize + "]";
 }
 
 //Get Mobile Id:
 public long getMobile_id() {
  return mobile.getId();		
 }
 
 public String getMobile_Name() {
  return mobile.getMobileName();
 }	
}
  • @Entity is used to annotate the classes to indicate that they are JPA entities.
  • @Table annotation is used to specify the name of the table that should be mapped with entities.
  • @Id annotation is used for the primary key.
  • The relationship between entities is shown using @OneToMany. mapped by element is added to indicate the entity that owns a bidirectional relationship.
  • @ManyToOne annotation is applied to the child entity to show a many-to-one relationship.
  • @JoinColumn is used to specify the foreign key column that references to parent table primary key.
  • I have used the Lombok library to remove boilerplate code. In case you want to know what is Lombok check this article https://codedec.com/tutorials/how-to-configure-lombok-into-eclipse/
  • Cascade.ALL will make sure that all persistence events that are performed on the parent object will be transferred to the child entity. for eg(If we persist Mobile entity all its child entities like the app too will be persisted)

Create Repository Interface

The repository here is the DAO layer, which performs all the database operations. MobileRepository and AppRepository interface is created which will extend JPARepository<ClassName, ID>.

MobileRepository

package com.abc.example.mapping.repository;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.abc.example.mapping.model.Mobile;
@Repository
public interface MobileRepository extends JpaRepository<Mobile, Long> {

 List<Mobile> findByMobileName(String mName);
}

AppRepository

package com.abc.example.mapping.repository;

import java.util.List;

import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.abc.example.mapping.model.Apps;
import com.abc.example.mapping.model.Mobile;
@Repository
public interface AppRepository extends JpaRepository<Apps, Long> {

 List<Apps> findByMobileId(long id);

 //List<Apps> findByMobileName(Mobile mobile);
}

Now, Go to OneToManyJpaApplication class and test our one-to-many relationship.

package com.abc.example.mapping;
import java.util.Collection;
import java.util.List;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

import com.abc.example.mapping.model.Apps;
import com.abc.example.mapping.model.Mobile;
import com.abc.example.mapping.repository.AppRepository;
import com.abc.example.mapping.repository.MobileRepository;

@SpringBootApplication
public class OneToManyJpaApplication {

 public static void main(String[] args) {
  ApplicationContext context = SpringApplication.run(OneToManyJpaApplication.class, args);
  MobileRepository mobileRepository = context.getBean(MobileRepository.class);
  AppRepository appRepository = context.getBean(AppRepository.class);
  
  //1. Save into db

    Mobile mobile = new Mobile("Galaxy","Samsung");
    mobileRepository.save(mobile); appRepository.save(new
    Apps("Whatsapp",25,mobile)); appRepository.save(new
    Apps("Be My Eyes",18,mobile)); appRepository.save(new
    Apps("Battleground",250,mobile)); 
  
   
 }

}

Now, Go to Run As > Spring Boot App. The tables will be created inside the database along with mapping.

Now, if we want to fetch records add the following code in the Application class:

//2. Find All.
  List<Mobile> mobiles = mobileRepository.findAll();
  for(Mobile m: mobiles) {
   System.out.println(m);
  }
  
  //3. Find By Mobile Name
  List<Mobile> name = mobileRepository.findByMobileName("Galaxy");
  for(Mobile m: name) {
   System.out.println(m);
  }
  
  //4. Getting parent table from child
  List<Apps> list= appRepository.findByMobileId(3);
  for(Apps a: list) {
   System.out.println(a.getMobile_Name());
  }

Run the Application once again and see the console for output. In this way, we learn how to map one-to-many relationships in Spring Data JPA.