簡體   English   中英

為什么@OneToMany 關系會生成額外的 SQL select 查詢?

[英]Why @OneToMany relations generate additional SQL select queries?

@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);
    }
}

在數據庫中,一位作者已經包含一本書。 我為一位作者創建了一本新書並想保存它。

但是當 function addBook 被調用時,現有的書是從數據庫中加載的。 我在日志中看到額外的 SQL 查詢:@Query["select book..."]

我該如何解決? 我不想有額外的 SQL 選擇

這就是 PersistentBag 的工作原理 - Hibernate 在您對列表執行操作時加載它。 我會簡單地用將創建的書引用到現有作者來代替將新書添加到作者的書列表

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);
    }
}

這樣做的原因是 JPA 工作的基本前提:你加載一個 object 圖,你操作它,在事務結束時 JPA 確保更改最終在數據庫中。

我看到有兩種方法可以避免 select。

  1. 反轉關系:當Book引用Author時,無需加載集合,因為它根本不存在。 如果您確實需要該集合,您始終可以為此使用專用查詢。

  2. 回到 SQL 並執行 SQL 插入語句。 當然,這會導致您的數據庫與 JPA 的一級緩存不一致。請確保您了解一級緩存的工作原理及其用途。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM