gpt4 book ai didi

java - 为什么 Hibernate @OneToOne 执行多个选择查询而不是一个?

转载 作者:行者123 更新时间:2023-11-30 12:04:05 24 4
gpt4 key购买 nike

这是我的实体:

@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 中进行查询,然后在 products 中进行查询。


这还不算,现在我们来做这样一个请求,一次接收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中发起一个request,获取所有products的id,然后1个request接收4个products。


在之前的查询中添加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中明确指定join fetch?可以做出这种默认行为吗?毕竟,使用 join 的单个查询总比很多查询要好。
  2. 为什么在不指定 join fetch 的情况下,附加的选择查询不会与 id in (...) 组合成一个查询?相反,Hibernate 一次选择一个。这可以定制吗?

最佳答案

n+1 获取策略是 Hibernate 的默认策略 - 只是因为,如 documentation 中所述

These defaults make sense for most associations in the majority of applications

要全局更改此行为,您可以设置 hibernate.default_batch_fetch_size,您会在互联网上找到一些关于 how to set proper value and why 的主题。

还有一件事 - 通常认为 fetch join 是所有问题的解决方案,但不是。我们必须记住 Cartesian Product Problem .

获取策略取决于我们的应用程序的工作方式、环境设置(例如数据库连接中的延迟)、我们使用的数据模型以及许多其他因素。没有一种适合所有人的解决方案,这就是为什么我们在 Hibernate 中有许多抓取策略

关于java - 为什么 Hibernate @OneToOne 执行多个选择查询而不是一个?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57296544/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com