簡體   English   中英

JPA / Hibernate Spring @Transactional vs. JOIN FETCH

[英]JPA / Hibernate Spring @Transactional vs. JOIN FETCH

我正面臨着有趣的 LazyInitializationException 解決方案。 為了防止這種情況(在 OneToMany 或 ManyToMany 上),一種已知的解決方案是使用 JOIN FETCH 查詢。 你可以看到她的幾個例子之一: https ://thoughts-on-java.org/best-practices-for-many-to-many-associations-with-hibernate-and-jpa/

其他更簡單的解決方案是使用 Spring 中的 @Transactional。 例如像這樣:

@DeleteMapping(value ="/product/{tagId}")
    @ResponseBody
    @Transactional
    public String deleteProductWithoutRelation(@PathVariable String product, Model model) {     
        Optional<Product> pr = productService.selectProduct(product);
        if (pr.isPresent()) {
            tag.get().getCustomer().size(); //usualy throws LazyInitializationException, 
                                            //without JOIN-FETCH Statment or @Transactional
        return deletedTagId;    
    }

當然,你可以在repository service 中放置@Transactional 的一些方法,來封裝這個解決方案。 那么這兩種解決方案的優點或缺點是什么?

這里有幾件事我們需要解開。

  1. @Transactional 無非是 Spring 確保打開數據庫連接(+ 事務)並再次關閉它。 就是這樣。
  2. 當您選擇一個包含惰性字段的實體時,您實際上是在說:我正在從我的實體中選擇“一些”字段,除了惰性字段。
  3. 但是,如果您稍后需要該惰性字段,因為您試圖在視圖(.html、.ftl、.jsp 等)中訪問它,則需要向數據庫發出另一個選擇以獲取它。
  4. 問題:此時,如果您@Transactional 方法之外,您將不再打開數據庫連接,因此會出現 LazyInitException。
  5. 總結一下:您的 fetch 確保為所有數據發出 1 個選擇。 如果你不這樣做,你需要一個開放的數據庫連接/事務,@Transactional 給你。

建議:您應該嘗試使用適當的 JPQL/Criteria/SQL 語句獲取呈現視圖所需的所有數據,而不要過多依賴重新選擇惰性字段。

暫無
暫無

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

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