代码之家  ›  专栏  ›  技术社区  ›  David Easley

在没有查询缓存的情况下从休眠二级缓存中检索所有foo?

  •  0
  • David Easley  · 技术社区  · 15 年前

    在他出色的博客中” Hibernate query cache considered harmful? “Terracotta公司的AlexMiller解释了为什么使用查询缓存会对延迟和可伸缩性造成危害。

    我的问题是:是否可以为使用二级缓存而不具有查询缓存的特定域对象类型编写“全部获取”DAO方法?

    我通常使用的这种方法的代码形式涉及查询缓存,例如:

    public List<Foo> getAllFoo()
    {
        return (List<Foo>) getHibernateTemplate().execute(new HibernateCallback()
        {
            public Object doInHibernate(Session session)
            {
                Query q = session.createQuery("from Foo");
                // Cache the results in the query cache.
                q.setCacheable(true);
                return q.list();
            }
        });
    }
    

    我唯一模糊的想法是在某个单例域对象(也被缓存)上维护所有foo的缓存集合。有更优雅的方式吗?

    1 回复  |  直到 15 年前
        1
  •  1
  •   Brian Deterling    15 年前

    如果使用的是ehcacheprovider,则需要访问cachemanager成员变量。不幸的是,它是私有的,没有公共访问方法,所以我最终创建了自己的ehcacheprovider副本,该副本使用带有公共静态方法的静态for cachemanager返回它。我假设您可以以相同的方式处理其他缓存提供程序,或者只实现缓存提供程序接口。

    一旦拥有了cachemanager,就可以使用cachemanager.get cache(类名)获取域(类)名称的缓存。它返回一个缓存,您可以使用cache.getkeys()迭代该缓存。每个键都是一个cache key,上面有实体ID,因此您可以使用cache.get(key)返回实际实体。

    如果您不介意绕过一些Java安全性,并且依赖于特定的Hibernate实现,那么另一个选项是:(异常处理省略):

      EhCacheProvider cp = (EhCacheProvider)((SessionFactoryImpl)session.getSessionFactory()).getSettings().getCacheProvider()
      Field f = EhCacheProvider.class.getDeclaredField("manager");
      f.setAccessible(true);
      CacheManager cm = (CacheManager)f.get(cp);
      Cache c = cm.get(Entity.class);