@Entity
public class Author {
@OneToMany(cascade = {PERSISTE, MERGE},
mappedBy = "author")
private List<Book> books = new ArrayList<>();
public void addBook(Book book) {
this.books.add(book);
book.setAuthor(this);
}
//other fields
}
@Entity
public class Book{
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "author_id")
private Author author;
}
public class BookService {
AuthorRepository repository;
@Transactional
public void saveBooks(){
Book newBook = new Book);
Author author = repository.findByid(1L);
author.addBook(newBook);
}
}
In a database, an author already contains one book. I create a new book for an author and want to save it.
But when the function addBook is called the existing book is loaded from the database. I see the additional SQL query in logs: @Query["select book ...."]
How can I fix it? I don't want to have additional SQL selects
CodePudding user response:
This is just how PersistentBag works - Hibernate loads it when you perform action on list. I would simply replace adding new Book to Author's books list with referencing created Book to existing Author
public class BookService {
BookRepository bookRepository;
AuthorRepository authorRepository;
@Transactional
public void saveBooks() {
Book newBook = new Book();
Author author = authorRepository.findByid(1L);
newBook.setAuthor(author);
bookRepository.save(newBook);
}
}
CodePudding user response:
The reason for this is the basic premise under which JPA works: You load an object graph, you manipulate it, at the end of the transaction JPA makes sure the changes end up in the database.
I see two ways to avoid the select.
reverse the relationship: When the
Book
references theAuthor
there is no need to load the collection, since it doesn't even exist in the first place. If you actually need the collection you can always use a dedicated query for that.Drop back to SQL and just execute a SQL insert statement. Of course this can lead to inconsistencies between your database and the 1st level cache of JPA. Make sure you understand how the 1st level cache works and what it is used for.