【发布时间】: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())