![](/img/trans.png)
[英]Why does Hibernate execute multiple SELECT queries instead of one when using @Fetch(FetchMode.JOIN)
[英]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个请求,这是我想要实现的。
因此,问题是:
createQuery
显式指定createQuery
join fetch
? 可以做出这种默认行为吗? 毕竟,使用join进行单个查询要好得多。 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.