Home > Blockchain >  Does JPA framework saves One-To-Many Relationship automatically?
Does JPA framework saves One-To-Many Relationship automatically?

Time:12-26

Suppose I've One-To-Many Relationship: One-To-Many

import javax.persistence.*;
import java.io.Serializable;
import java.util.Set;

@Entity
@Table(name = "books")
public class Book implements Serializable {

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

    private String title;
    private String author;
    @Column(unique = true)
    private String isbn;

    @OneToMany(mappedBy = "book", fetch = FetchType.LAZY,
            cascade = CascadeType.ALL)
    private Set<Page> pages;

    public Book() {
    }

    public Book(String title, String author, String isbn) {
        this.title = title;
        this.author = author;
        this.isbn = isbn;
    }

    // getters and setters, equals(), toString() .... (omitted for brevity)
}

And

import javax.persistence.*;
import java.io.Serializable;

@Entity
@Table(name = "pages")
public class Page implements Serializable {

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

    private int number;
    private String content;
    private String chapter;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "book_id", nullable = false)
    private Book book;

    public Page() {
    }

    public Page(int number, String content, String chapter, Book book) {
        this.number = number;
        this.content = content;
        this.chapter = chapter;
        this.book = book;
    }

    // getters and setters, equals(), toString() .... (omitted for brevity)
}

And store it with:

// create a new book
Book book = new Book("Java 101", "John Doe", "123456");
    
// save the book
bookRepository.save(book);
    
// create and save new pages
pageRepository.save(new Page(1, "Introduction contents", "Introduction", book));
pageRepository.save(new Page(65, "Java 8 contents", "Java 8", book));
pageRepository.save(new Page(95, "Concurrency contents", "Concurrency", book));

The question is: do I really need to save every page manually? Can I just work with java collections and then just save the main entity like:

book.pages.add(new Page(1, "Introduction contents", "Introduction", book));

book.pages.add(new Page(65, "Java 8 contents", "Java 8", book));

book.pages.add(new Page(95, "Concurrency contents", "Concurrency", book));

bookRepository.save(book);

The example was taken from https://attacomsian.com/blog/spring-data-jpa-one-to-many-mapping

And I wanna know the right and the best way to store relationships, that's why I'm asking here and not just experiment by myself, because it seems the article misleading tons of people

CodePudding user response:

Here is what cascade on the Book#pages comes into play. As you configured it as CascadeType.ALL , it means that when you use EntityManager to persist() on a Book , it will automatically call persist() on all its Page.

With cascade is disable , you have to call the following to save a new Book and all of its page :

entityManager.persist(book);
entityManager.persist(page1);
entityManager.persist(page2);
....
entityManager.persist(pageN);

But with cascade is enable , you just have to call the following as all the persist() on Page will be cascaded to be called automatically.

entityManager.persist(book);

As the spring-data-jpa repositories internally just use the same EntityManager to save objects for the same transaction , you just need to call the following to save the book and its page if cascade is enable :

Book book = new Book("Java 101", "John Doe", "123456");
book.pages.add(new Page(1, "Introduction contents", "Introduction", book));
book.pages.add(new Page(65, "Java 8 contents", "Java 8", book));
book.pages.add(new Page(95, "Concurrency contents", "Concurrency", book));
bookRepository.save(book);

Otherwise if cascade is disable , you have to call the followings to save a Book and its page :

Book book = new Book("Java 101", "John Doe", "123456");
bookRepository.save(book);

pageRepository.save(new Page(1, "Introduction contents", "Introduction", book));
pageRepository.save(new Page(65, "Java 8 contents", "Java 8", book));
pageRepository.save(new Page(95, "Concurrency contents", "Concurrency", book));
  • Related