簡體   English   中英

Hibernate @OneToOne為什么執行多個選擇查詢而不是一個?

[英]Why does Hibernate @OneToOne execute multiple select queries instead of one?

這是我的實體:

@Entity
public class ProductStateEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Integer id;

    @OneToOne
    @JoinColumn(name = "product_id", nullable = false)
    private ProductEntity product;

    // other fields
}


@Entity
public class ProductEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Integer id;

    // other fields
}

如果我以這種方式提出要求:

session.get(ProductStateEntity.class, 10);

SQL是這樣形成的:

SELECT product_states.id, product_states.product_id, products.id, -- other columns
FROM product_states
INNER JOIN products ON product_states.product_id=products.id
WHERE product_states.id=10

到目前為止,使用INNER JOIN效果很好。


如果您以這種方式發出請求:

session.createQuery("from ProductStateEntity where id = :id")
            .setParameter("id", 10)
            .list()

SQL是這樣形成的:

SELECT product_states.id, product_states.product_id, -- other columns
FROM product_states
WHERE product_states.id=10;

SELECT products.id, -- other columns
FROM products
WHERE products.id=10

在這種情況下,將發出2個請求。 首先在product_states中進行查詢,然后在product中進行查詢。


不僅如此,現在我們將發出這樣的請求,該請求一次接收4條ID為4的記錄:

session.createQuery("from ProductStateEntity where id in :ids")
            .setParameter("ids", Arrays.asList(10, 11, 12, 13))
            .list();

SQL是這樣形成的:

SELECT product_states.id, product_states.product_id, -- other columns
FROM product_states
WHERE product_states.id IN (10, 11, 12, 13);

SELECT products.id, -- other columns
FROM products
WHERE products.id=10;

SELECT products.id, -- other columns
FROM products
WHERE products.id=11;

SELECT products.id, -- other columns
FROM products
WHERE products.id=12;

SELECT products.id, -- other columns
FROM products
WHERE products.id=13;

在這種情況下,發出了5個請求。 首先,在product_states中發出一個請求,獲取所有產品的ID,然后根據1個請求進行處理,以接收4個產品中的每一個。


join fetch添加到上一個查詢:

session.createQuery("from ProductStateEntity p join fetch p.product where p.id in :ids")
            .setParameter("ids", Arrays.asList(10, 11, 12, 13))
            .list();

SQL是這樣形成的:

SELECT product_states.id, products.id, product_states.product_id, -- other columns
FROM product_states
INNER JOIN products ON product_states.product_id=products.id
WHERE product_states.id IN (10, 11, 12, 13)

因此,使用INNER JOIN只會發出1個請求,這是我想要實現的。


因此,問題是:

  1. 為什么需要在createQuery顯式指定createQuery join fetch 可以做出這種默認行為嗎? 畢竟,使用join進行單個查詢要好得多。
  2. 為什么在不指定join fetch ,其他選擇查詢未id in (...)合並為id in (...)id in (...)查詢? 相反,Hibernate一次只能選擇一個。 可以定制嗎?

n+1提取策略是Hibernate的默認策略-正因為如文檔所述

這些默認值對於大多數應用程序中的大多數關聯有意義

要全局更改此行為,可以設置hibernate.default_batch_fetch_size ,您將在Internet上找到一些有關如何設置適當值以及原因的主題。

還有另一件事-普遍認為fetch join是解決每個問題的解決方案,但事實並非如此 我們必須記住笛卡爾積問題

提取策略取決於我們的應用程序如何工作,環境設置是什么(例如,數據庫連接中的延遲),我們使用什么數據模型以及許多其他事情。 沒有一種適合所有人的好的解決方案,這就是為什么我們在Hibernate中有許多獲取策略的原因

暫無
暫無

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

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