@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);
}
}
在数据库中,作者已经包含一本书。我为作者创建了一本新书,并希望保存它。
但是当调用函数addBook时,现有的图书将从数据库加载。我在日志中看到了额外的SQL查询:@Query[“选择图书...."]
我该如何解决这个问题?我不希望有额外的SQL选择
2条答案
按热度按时间nwo49xxi1#
这就是PersistentBag的工作原理--当你在列表上执行操作时,Hibernate会加载它。我只需要简单地将添加新书替换为将创建的书引用到现有的Author
yk9xbfzb2#
其原因是JPA工作的基本前提:加载对象图,操作对象图,在事务结束时,JPA确保更改在数据库中结束。
我认为有两种方法可以避免选择。
1.颠倒关系:当
Book
引用Author
时,不需要加载集合,因为它根本不存在,如果你真的需要这个集合,你可以使用一个专门的查询。1.回到SQL,只执行一个SQL插入语句。当然,这可能会导致数据库和JPA的一级缓存之间的不一致。请确保您了解一级缓存的工作原理及其用途。