Implementing Many to Many Mapping in Spring Boot using JPA

Posted By : Shanu Kumar | 28-Apr-2018

In this blog,I am going to continues my mapping series with entities.if you missed my last blog which is based on

One_to_Many mapping, you can check here

Tody,I am going to implement Many-to-Many database relationship using JPA and Hibernate at the object level. 

for this, Simply we are going to create the project.

Consider the following tables, Cart, Item and Cart_Items tables.Basically, the concept is  A Cart has multiple items and Every item can be part of multiple carts.so we have a many to many mapping here.

 

Creating the Project

     --> Using Spring Initializr web tool

 

Here we are going to generate the project from Spring Initializr web tool.

      1. Go to http://start.spring.io

      2. Click Switch to full version link to see all the options

      3. Enter Artifact as “demo” 

      4. Change Package Name to “com.example.app” 

      5. Select JPA, WEB and MYSQL dependencies.

      6. Click Generate Project to download the project.

Database and Logging Configuration

in this application, we are using MYSQL as a database.so need to configure the database URL, username and password according to our local database configuration.To implement this configuration, we find out application.properties file in src/main/resource/application.properties and add the following properties-

server.port=8585
spring.jpa.hibernate.ddl-auto=update
spring.jpa.database-platform = org.hibernate.dialect.MySQL5Dialect
spring.datasource.url= jdbc:mysql://localhost:3306/many_to_many?autoReconnect=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
# Hibernate

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type=TRACE
        

here the server port is 8585 and my schema name is many_to_many

Now, we have to create Domain 

 Domain Models

After configuring the database, now let's start to define models for application - Cart and Item.

For this, we simply create a packagefor  model inside com.example.app.model and write code in the following classes inside this package.

1. Cart model

   package com.example.app.model;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "carts")
public class Cart {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    
    @Size(max = 100)
    @Column(unique = true)
    private Long cart_total;


    @NotNull
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "created_at")
    private Date createdAt = new Date();

    @NotNull
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "last_updated_at")
    private Date lastUpdatedAt = new Date();


    @ManyToMany(fetch = FetchType.LAZY,
            cascade = {
                CascadeType.PERSIST,
                CascadeType.MERGE
            })
    @JoinTable(name = "cart_items",
            joinColumns = { @JoinColumn(name = "cart_id") },
            inverseJoinColumns = { @JoinColumn(name = "item_id") })
    private Set carts = new HashSet<>();


    public Cart() {

    }

    public cart(Long cart_total) {
        this.cart_total = cart_total;
    }

    // Getters and Setters (Omitted for brevity)
}
             
        

2. Item model

package com.example.app.model;

import org.hibernate.annotations.NaturalId;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "items")
public class Item {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotNull
    private String description;

    @NotNull
    private long price;

    @ManyToMany(fetch = FetchType.LAZY,
            cascade = {
                CascadeType.PERSIST,
                CascadeType.MERGE
            },
            mappedBy = "items")
    private Set items = new HashSet<>();

    public Item() {

    }

    public Item(String description, Long price) {
        this.description = description;
        this price=price;
    }

    // Getters and Setters (Omitted for brevity)
}
      
        

we are using @ManyToMany annotation for creating the relationship between these entities and this annotation is used in both table 

but one table can be  owner of  this relationship.

Here, Cart entity is the Owner of the relationship.

 

Defining  Repositories

now we are going to  create a package for repository inside com.example.app. and create the following interfaces.

 

1. CartRepository

package com.example.app.repository;

import com.example.app.model.Cart;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface CartRepository extends JpaRepository {

}
   
        

2. ItemRepository

package com.example.app.repository;

import com.example.app.model.Item;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ItemRepository extends JpaRepository {

}

        

code part is complete, now run and test the application.

Open the main class DemoApplication.java and replace it with the following code -

package com.example.app;

import com.example.app.model.Cart;
import com.example.app.model.Item;
import com.example.app.repository.CartRepository;
import com.example.app.repository.ItemRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class JpaManyToManyDemoApplication implements CommandLineRunner {

    @Autowired
    private ItemRepository itemRepository;

    @Autowired
    private CartRepository cartRepository;

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
       
        Cart cart = new Cart(1);

        // Create two Items
        Item item1 = new Item("Whey Protin",2000);
        Item item2 = new Item("Amino Energy",1200);


        // Add item references in the cart
        cart.getItems().add(item1);
        post.getItems().add(item2);

        // Add cart reference in the Item
        item1.getCarts().add(cart);
        item2.getCarts().add(cart);

        cartRepository.save(cart);

        // =======================================

    }
}    

Finally ,we done. You can check your entries in your database.

Hope so, this article is useful to you.

Thank you so much.

About Author

Author Image
Shanu Kumar

Shanu has experience in Java EE & Java SE and also interested in EJB application. He has knowledge of SQL and worked on MYSQL & Oracle databases. He loves listening to music.

Request for Proposal

Name is required

Comment is required

Sending message..