Skip to main content

How to Implement One to Many and Many to One Mapping in Spring Boot using JPA

Spring Boot CRUD example using One-to-Many and Many to One mapping | With Thymeleaf User Interface

Spring Boot CRUD example using One-to-Many and Many to One mapping | With Thymeleaf User Interface

In this tutorial, we will learn how to use @OneToMany and @ManyToOne annotation using JPA (Java Persistent API) in Spring Boot. We also attach Thymeleaf for User Interface.

In past tutorial, we already created Spring Boot CRUD with Rest API, JPA and MySql. Please refer that one first, we will continue from there.

For applying One to Many relationship, we need another POJO class. In past we already created Book class, now we will create new class Author.

As we know Author have multiple Books, so we can easily apply One to Many operation. Lets create POJO class for Author and apply @OneToMany on Book

Define List of Book and apply @OneToMany annotation on field. We are using mappedBy property, so Author table does not create new column. 

We already learn about mappedBy property in One-to-One annotation. Please refer that if you want to know more about it.

1. Create Author class

Author.java

import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name = "author")
public class Author {

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

    @Column
    private String authorName;

    @OneToMany(mappedBy = "author")
    private List<Book> books;

    public int getId() {
        return id;
    }

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

    public String getAuthorName() {
        return authorName;
    }

    public void setAuthorName(String authorName) {
        this.authorName = authorName;
    }

    public List<Book> getBooks() {
        return books;
    }

    public void setBooks(List<Book> books) {
        this.books = books;
    }

}

For Bidirectional approach, we also have to apply @ManyToOne annotation in Book class.

Book.java

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

@Entity
@Table(name = "book")
public class Book {

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

    @Column
    private String bookname;

    @Column
    private int price;

    @ManyToOne
    private Author author;


    public int getId() {
        return id;
    }

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

    public String getBookname() {
        return bookname;
    }

    public void setBookname(String bookname) {
        this.bookname = bookname;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public Author getAuthor() {
        return author;
    }

    public void setAuthor(Author author) {
        this.author = author;
    }

}

2. Create Repository Class

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

import com.example.model.Author;

public interface AuthorRepository extends JpaRepository<Author, Integer>{

}

3. Create Service Class

AuthorService.java

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.model.Author;
import com.example.repository.AuthorRepository;

@Service
public class AuthorService {
    
    @Autowired
    AuthorRepository authorRepo;
    
    public List<Author> loadAll() {
        return (List<Author>) authorRepo.findAll();
    }

    public Author loadAuthorById(int id) {
        return authorRepo.findById(id).get();
    }
    
    public Author saveAuthor(Author author) {
        authorRepo.save(author);
        return loadAuthorById(author.getId());
    }

}

4. Create Controller Class

AuthorController.java

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import com.example.model.Author;
import com.example.service.AuthorService;

@Controller
@RequestMapping("/author")
public class AuthorController {
    
    @Autowired
    AuthorService authorService;

    @GetMapping()
    private String getAllAuthors(Model model) {
        List<Author> list = authorService.loadAll();
        model.addAttribute("allAuthor", list);
        return "index";
    }
    
    @GetMapping("/new")
    public String addNewAuthor(Model model) {
        Author author = new Author();
        model.addAttribute("author", author);
        return "add-author";
    }
    
    @PostMapping("/save")
    public String saveAuthor(@ModelAttribute("author") Author book) {
        authorService.saveAuthor(book);
        return "redirect:/books";
    }
}

While saving we need all saved author list, So we also need to add one line of code into book.java "/new" API. 

@GetMapping("/new")
 public String showNewBookPage(Model model) {
        Book book = new Book();
        List<Author> authorList = authorService.loadAll();
        model.addAttribute("authorList", authorList);
        model.addAttribute("book", book);
        return "add-book";
 } 

For OneToMany and ManyToOne tutorial we need only save functionality so edit and delete are not included for Author class.

Now Lets go to UI part.

5. Add new Author

Include following code into index.html file

<a href="/author/new">
     <button>Add New Author</button>
</a>

After this we will get "Add New Author" button in main page.

6. Save Author Page

add-author.html

<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <title>Add New Author</title>
    </head>
    <body>
        <div align="center">
            <form action="#" th:action="@{/author/save}" th:object="${author}" method="post">
    
                <table border="0" cellpadding="10">
                    <tr>
                        <td>Author:</td>
                        <td><input type="text" th:field="*{authorName}" /></td>
                    </tr>
                    <tr>
                        <td colspan="2"><button type="submit">Save</button> </td>
                    </tr>
                </table>
            </form>
        </div>
    </body>
</html>

Run Spring Boot application, save some author.

one to many and many to one mapping table
Author table

For displaying all saved authors while saving book, we need to change some code "add-book.html".

add-book.html

<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Add New Book</title>
</head>
<body>
    <div align="center">
        <form action="#" th:action="@{/books/save}" th:object="${book}"
            method="post">

            <table border="0" cellpadding="10">
                <tr>
                    <td>Book Name:</td>
                    <td><input type="text" th:field="*{bookname}" /></td>
                </tr>
                <tr>
                    <td>Author:</td>

                    <td><select th:field="*{author}">
                        <option th:each="author : ${authorList}" th:value="${author.id}"
                                th:text="${author.authorName}"></option>
                    </select></td>
                </tr>

                <tr>
                    <td>Price:</td>
                    <td><input type="text" th:field="*{price}" /></td>
                </tr>
                <tr>
                    <td colspan="2"><button type="submit">Save</button></td>
                </tr>
            </table>
        </form>
    </div>
</body>
</html>

Highlighted code will display all saved author.

  • We are displaying all saved authors in drop-down. Here we can select any author and Book table stores foreign key of Author in author_id column
     
one to many and many to one mapping table

  • Saving Book data with Author name.

save onetomany and manytoone data



  • Book table with Author's table foreign key author_id.
One-to-many and many-to-one foreign key

  •  All saved Book with Author.

One-to-many example in Spring Boot JPA

Conclusion :

  1. We learned how to use @OneToMany and @ManyToOne mapping in Spring Boot with using JPA.
  2. Created POJO, Service and Controller classes and Jpa Repository Interface for reading and writing author data.
  3. Display all saved authors in drop-down.
  4. Learned how database tables stores foreign key of another table using one-to-many mapping.


 

RECOMMENDED TUTORIALS :

Comments

Popular posts from this blog

Flipping the Matrix HackerRank Solution in Java with Explanation

Java Solution for Flipping the Matrix | Find Highest Sum of Upper-Left Quadrant of Matrix Problem Description : Sean invented a game involving a 2n * 2n matrix where each cell of the matrix contains an integer. He can reverse any of its rows or columns any number of times. The goal of the game is to maximize the sum of the elements in the n *n submatrix located in the upper-left quadrant of the matrix. Given the initial configurations for q matrices, help Sean reverse the rows and columns of each matrix in the best possible way so that the sum of the elements in the matrix's upper-left quadrant is maximal.  Input : matrix = [[1, 2], [3, 4]] Output : 4 Input : matrix = [[112, 42, 83, 119], [56, 125, 56, 49], [15, 78, 101, 43], [62, 98, 114, 108]] Output : 119 + 114 + 56 + 125 = 414 Full Problem Description : Flipping the Matrix Problem Description   Here we can find solution using following pattern, So simply we have to find Max of same number of box like (1,1,1,1). And last

Plus Minus HackerRank Solution in Java | Programming Blog

Java Solution for HackerRank Plus Minus Problem Given an array of integers, calculate the ratios of its elements that are positive , negative , and zero . Print the decimal value of each fraction on a new line with 6 places after the decimal. Example 1 : array = [1, 1, 0, -1, -1] There are N = 5 elements, two positive, two negative and one zero. Their ratios are 2/5 = 0.400000, 2/5 = 0.400000 and 1/5 = 0.200000. Results are printed as:  0.400000 0.400000 0.200000 proportion of positive values proportion of negative values proportion of zeros Example 2 : array = [-4, 3, -9, 0, 4, 1]  There are 3 positive numbers, 2 negative numbers, and 1 zero in array. Following is answer : 3/6 = 0.500000 2/6 = 0.333333 1/6 = 0.166667 Lets see solution Solution 1 import java.io.*; import java.math.*; import java.security.*; import java.text.*; import java.util.*; import java.util.concurrent.*; import java.util.function.*; import java.util.regex.*; import java.util.stream.*; import static java.util.st