Hibernate通过主键在列表中查找直接到L2缓存

发布于 2024-12-10 06:48:23 字数 245 浏览 1 评论 0原文

我有一个带有简单长主键的实体。 我执行如下查询: Select from table where Primary_key IN (....);

Hibernate 似乎想要执行一个查询来获取 Id(我刚刚指定的!),然后转到 L2 缓存。有什么办法可以跳过初始查询吗?我只想要一组按主键的实体。 不确定这是 JPA 1 还是 JPA 2.0(更好地支持列表)。

我可以在循环中执行 findById() 并获得所需的结果,但这显然不是最佳的。

I have an Entity with a simple long primary key.
I do a Query like: Select from table where primary_key IN (....);

Hibernate seems to want to do a query to get the Ids (that I just specified!) and then go to the L2 cache. Is there any way to skip the initial query? I just want a set of Entities by primary key.
Not sure if this is a JPA 1, vs JPA 2.0 (which supports Lists better).

I can do findById() in a loop and get the desired result, but this is obviously not optimal.

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

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

发布评论

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

评论(1

郁金香雨 2024-12-17 06:48:23

您需要启用查询缓存 并且这个特定查询可以缓存。这仅在 JPA 2.0 中通过提示可用。

query.setHint(“org.hibernate.cacheable”, true);

并通过设置以下属性来启用查询缓存

hibernate.cache.use_query_cache true

另一个解决方案是在循环中使用 getReference 并启用批量加载。如果实例存在于缓存中,它将从缓存中返回 - 如果不存在,则在访问第一个代理对象时,它将触发一个查询来加载一批这些对象。您可以将其隐藏在实用函数后面。

public List<T> findMany(Class<T> entityClass,List<? extends Serializable> ids) {
  List<T> result = new ArrayList<T>;
  for(Serializable id:ids) {
     result.add(entityManager.getRefrence(id));
  }

  for(T entity:result) {
    // force initialization of proxies, if batch loading is enabled
    // this shouldn't lead to one query per entity
    Hibernate.initialize(entity); 
  }
  return result;      
} 

这可能需要一些调整 - 尚未测试 - 特别是泛型部分。

You will need to enable query caching and this specific query as cache able. This only available in JPA 2.0 via hints.

query.setHint(“org.hibernate.cacheable”, true);

And enable the query cache by setting the following property

hibernate.cache.use_query_cache true

Another solution would be to use getReference in a loop and enable batch loading. If the instance exists in the cache it will be returned from cache - if not when the first proxied object is accessed it will fire one query to load a batch of those. You could hide this behind a utility function.

public List<T> findMany(Class<T> entityClass,List<? extends Serializable> ids) {
  List<T> result = new ArrayList<T>;
  for(Serializable id:ids) {
     result.add(entityManager.getRefrence(id));
  }

  for(T entity:result) {
    // force initialization of proxies, if batch loading is enabled
    // this shouldn't lead to one query per entity
    Hibernate.initialize(entity); 
  }
  return result;      
} 

This might need a few tweaks - haven't tested it - especially the generics part.

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