首页 > 解决方案 > 通过 id 以外的其他列进行休眠缓存

问题描述

I am trying to properly set the caching mechanism for Hibernate + Hazelcast (in Spring 4) and I am facing some problems when the select is done by a different column than the 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

标签: hibernatehazelcast

解决方案


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

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

如果你想用不同的key访问实体,例如 authorId,你需要设置一个不同的hash map自己处理缓存过程(如果在case中没有找到实体,从数据库中获取它并放入缓存中) . 例如, JCache可以帮助该过程,Hazelcast 也是一个实现。

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


推荐阅读