休眠:batch_size?二级缓存?

发布于 2024-08-03 17:49:33 字数 804 浏览 6 评论 0原文

我有一个 Hibernate 域对象,它由应用程序的不同部分加载。有时,延迟加载每个关联是有利的,而其他关联则最好在一个连接中加载整个事物。作为我发现的一种希望令人满意的妥协:

使用批量获取,如果访问一个代理,Hibernate 可以加载多个未初始化的代理。批量抓取是惰性选择抓取策略的优化。

hibernate.default_batch_fetch_size< /代码>

使用批量获取,Hibernate 可以加载多个未初始化的代理 如果访问一个代理。批量抓取是一种优化 惰性选择获取策略。

我还看到:

hibernate.jdbc.fetch_size

非零值决定 JDBC 获取大小(调用 Statement.setFetchSize())。

Hibernate 是否足够智能,可以在批量获取时查看二级缓存?即,对关联的初始调用进行一次提取,然后接下来的 X 个调用会命中缓存?这样我就可以实现我想要的延迟加载,而且还可以经常访问缓存以进行更多类似批量的事务。

如果集合的全部内容已经包含在缓存中,它仍然会在访问集合时执行获取查询吗?

谢谢。

I have a Hibernate domain object that gets loaded by different parts of the application. Sometimes it's advantageous to lazy load every association and others it's better to load the entire thing in one join. As a hopefully happy compromise I've found:

Using batch fetching, Hibernate can load several uninitialized proxies if one proxy is accessed. Batch fetching is an optimization of the lazy select fetching strategy.

hibernate.default_batch_fetch_size:

Using batch fetching, Hibernate can load several uninitialized proxies
if one proxy is accessed. Batch fetching is an optimization of the
lazy select fetching strategy.

I also see:

hibernate.jdbc.fetch_size:

A non-zero value determines the JDBC fetch size (calls Statement.setFetchSize()).

Well is Hibernate smart enough to look in the second-level cache when doing the batch fetching? i.e Do one fetch for the initial call to the association and then the next X calls hit the cache? That way I can have the lazy loading I desire but also hit the cache often for the more bulk-like transactions.

If entire contents of the collection is already contained in the cache, would it still execute the fetching queries on access of the collection?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

孤独岁月 2024-08-10 17:49:33

我今天做了很多研究,并能够找到对我自己的问题的答案。我正在查看 Hibernate 代码,流程如下所示:

集合是否已初始化?

  • 不?是否进行批量获取(通过批量获取获取的项目放入缓存中)
  • 是吗?在缓存中查找特定项目,如果不存在,则进行批量提取。

因此,如果在缓存中找到您要查找的集合中的项目,则不会发生批量提取。如果在二级缓存中未找到该项目,则会进行批量提取,但无论批量项目是否在缓存中,它都会提取批量项目。


----- 示例 1 -----

优点:(

集合中的三项 - 批量大小为 3)
第一个:

  • collection.getItem(0) - 无缓存 |批量获取 3 个项目
  • collection.getItem(1) - 通过批量获取加载
  • collection.getItem(2) - 通过批量获取加载

现在,在其他地方,稍后:

  • collection.getItem(0) - 缓存命中
  • 集合.getItem(1) - 缓存命中
  • collection.getItem(2) - 缓存命中

----- 示例 2 -----

坏处:(

集合中的三个项目 - 批量大小为 3)

在本例中,该项目索引 0 处的数据已从缓存中删除,因为缓存可能已满并且该项目已被删除,或者该项目已过时或空闲。

  • collection.getItem(0) - 不在缓存中,所以 Batch Of 3 (select * where id in (?, ?, ?))
  • collection.getItem(1) - 已经在缓存中(无论如何都被批量获取替换)
  • collection.getItem (2) - 已经在缓存中(无论如何都被批量获取所取代)

因此,这里的权衡是,由于批处理,您将有更少的 SQL 调用,但您会更频繁地丢失缓存。有一个打开的票证,可以在二级缓存中进行批处理,然后再将其发送到数据库。

http://opensource.atlassian.com/projects/hibernate/browse/HHH-第1775章

投票吧!

I did a lot of research today and was able to dig up a response to my own question. I was looking through the Hibernate code and the flow looks like this:

Is the collection initialized?

  • No? Do a batch fetch (items obtained by batch-fetch are placed in the cache)
  • Yes? Look in the cache for the particular item, if it's not there do a batch-fetch.

So if the item in the collection you're looking for IS FOUND in the cache then the batch-fetch doesn't happen. If the item IS NOT found in the second-level cache then the batch fetch happens, BUT it will do a fetch of batched items REGARDLESS of whether the batched items are in the cache.


----- EXAMPLE 1 -----

The Good:

(Three items in a collection - batch size of 3)
The first go:

  • collection.getItem(0) - No cache | batch-fetch 3 items
  • collection.getItem(1) - Loaded in by batch-fetch
  • collection.getItem(2) - Loaded in by batch-fetch

Now, somewhere else, later in time:

  • collection.getItem(0) - Cache Hit
  • collection.getItem(1) - Cache Hit
  • collection.getItem(2) - Cache Hit

----- EXAMPLE 2 -----

The Bad:

(Three items in a collection - batch size of 3)

In this case, the item at index 0 was removed from the cache because maybe the cache was full and the item was dropped, or the item went stale or idle.

  • collection.getItem(0) - Not In Cache So Do Batch Of 3 (select * where id in (?, ?, ?))
  • collection.getItem(1) - In Cache Already (replaced by batch-fetch anyway)
  • collection.getItem(2) - In Cache Already (replaced by batch-fetch anyway)

So the trade off here is that you'll have fewer SQL calls due to batching, but you'll be missing you cache more often. There is a ticket open to have the batching look in the second-level cache before it goes out to the database.

http://opensource.atlassian.com/projects/hibernate/browse/HHH-1775

Vote it up!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文