我的应用程序已经使用Spring缓存来缓存查询结果,所以我不想要任何Hibernate缓存。更准确地说,我发现Hibernate将返回的实体保存在持久化上下文中,然后每当我做更多的事情时,它都会试图自动刷新这些实体(甚至Hibernate也发现最后没有变化)。为了解决这个问题,我需要在每次调用一些存储库方法之后调用entityManager.clear()
。如何在使用Spring caching + Spring JPA Data repository时关闭Hibernate缓存?
下面是一个示例仓库:
@Repository
public interface SampleRepository extends JpaRepository<Sample, String> {
@Cacheable
Optional<Sample> findById(String id);
}
2条答案
按热度按时间yizd12fk1#
你可能想看看hibernates
StatelessSession
。它没有缓存/持久化上下文。但除此之外,我感觉你的会议可能会很大。如果会话(和事务)范围尽可能的小,那么您遇到的问题就不会真正出现(实体在持久化上下文中保留太长时间)。
你在做批处理吗?如果是,则将批处理工作划分为较小的事务或会话交互可能是一种方法
2ic8powd2#
作为一个一般的经验法则(从我这里),不要对JPA实体使用
@Cacheable
,这几乎总是会导致令人惊讶的结果/副作用。想象以下
现在,当使用
findById
方法检索Sample
并更改其某些属性时,它最终将被持久化。现在,findById
缓存有一个更新的Sample
示例。现在,如果
findByName
缓存没有与将要添加的Sample
实体相同的Sample
实体,则没有问题,但是如果它确实具有相同的Sample
实体,则不会有更新的记录。即使它引用相同的数据,它也不会引用相同的Sample
示例。这将导致惊人的结果。当然,你可以这样做,当你调用
save
(这是不需要的),它将销毁所有缓存,但这种挫败缓存的目的。其次,如果有人不调用保存,因为它是一个托管实体,它将自动持久化。因此,与其在这里使用
@Cacheable
,不如使用JPA提供程序的二级缓存,可能是Hibernate。它会照顾所有这些事情。