【问题标题】:Hibernate cache by other column than id通过 id 以外的其他列进行休眠缓存
【发布时间】:2020-09-15 07:54:24
【问题描述】:

我正在尝试正确设置Hibernate + Hazelcast的缓存机制(在Spring 4),当SELECT由不同的列完成时,我面临的一些问题而不是ID。下面是我的模型的简化版本:

@Cache(usage = CacheConcurrencyStrategy.READ_WRITE,
        region = HibernateCacheConstants.LISTENER_REGION_NAME)
@Entity
@Table(name = "books")
public class Book {
    @Id
    @Column
    UUID id;

    @Column
    String name;

    @Column
    UUID authorId;
}

现在,我对 Hibernate 进行了以下配置:

properties.setProperty("hibernate.show_sql", "true"); // temporary activated to see exactly the DB hits
properties.setProperty("hibernate.cache.use_second_level_cache", "true");
properties.setProperty("hibernate.cache.region.factory_class",
                "com.hazelcast.hibernate.HazelcastLocalCacheRegionFactory");

现在,一些测试: 按 ID 检索时

booksDao.get(bookId); // hits the database. Looged:
// Hibernate: select this_.id as id1_0_0_, this_.name as name2_0_0_, this_.author_id as authorId_se3_0_0_ from LIBRARY.books this_ where this_.id in (?)
booksDao.get(bookId); // retrieved from cache, as intended
booksDao.get(bookId); // retrieved from cache, as intended
booksDao.getByAuthorId(authorIdId); // hits the database. Looged:
// Hibernate: select this_.id as id1_0_0_, this_.name as name2_0_0_, this_.author_id as author_se3_0_0_ from LIBRARY.books this_ where this_.author_id in (?)
booksDao.getByAuthorId(bookId); // hits the database, just as above
booksDao.getByAuthorId(bookId); // hits the database, just as above

来自 DAO 的方法:

public List<Book> getByAuthorId(UUID... authorIds) {
        if (authorIds== null || authorIds.length == 0) {
            return Collections.emptyList();
        }

        Criteria criteria = getCurrentSession().createCriteria(Book.class)
                .add(in("authorId", authorIds));

        @SuppressWarnings("unchecked")
        List<Book> books= criteria.list();
        return books;
    }

考虑到我经常通过作者 ID 搜索的情况,我希望这也被缓存,但无法做到这一点。另外,我想避免激活 hibernate.cache.use_query_cache

【问题讨论】:

  • 为什么要避免激活查询缓存?它完全符合您的目的,可以根据查询激活
  • 我读到查询缓存会增加很多开销并且不是很有效。此外,该示例是一个非常简化的版本,因此查询缓存可能甚至不适用于实际执行的查询。
  • 查询缓存肯定有缺点,但它可能很有用,尤其是在您的应用程序不经常写入的情况下。最好的办法是对其进行测试(根据标准调用 .setCacheable())

标签: hibernate hazelcast


【解决方案1】:

这不是 Hibernate 二级缓存的工作方式。

缓存基本上是一个哈希映射。键是 ID,值是实体(为了简化)。

如果你想使用不同的键访问实体例如 authorId,你需要设置一个不同的哈希映射句柄自己的缓存过程(如果在case中没有找到实体,从数据库中获取并放入缓存中)。例如,JCache 可以帮助该过程,Hazelcast 也是一个实现。

但是,现在,您有 2 个彼此不同步的缓存。根据您的用例,它可能没问题,也可能会导致很多麻烦。

【讨论】:

  • 我明白了。我认为有可能为它配置两个保持同步的缓存(一个按 ID,一个按 authorId),但我在文档中找不到。
猜你喜欢
  • 2019-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多