Reputation: 3059
Suppose I've One-To-Many Relationship:
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
Upvotes: 0
Views: 529
Reputation: 90517
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
disabled, you have to call the following to save a new Book
and all of its pages:
entityManager.persist(book);
entityManager.persist(page1);
entityManager.persist(page2);
....
entityManager.persist(pageN);
But with cascade
enabled, 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 pages if cascade
is enabled:
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 disabled, you have to call the following to save a Book
and its pages:
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));
Upvotes: 1