繁体   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