java 可以在没有Hibernate管理实体的情况下编写Spring JPA数据存储库接口吗?

raogr8fs  于 2023-10-14  发布在  Java
关注(0)|答案(2)|浏览(97)

我的应用程序已经使用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);
}
yizd12fk

yizd12fk1#

你可能想看看hibernates StatelessSession。它没有缓存/持久化上下文。
但除此之外,我感觉你的会议可能会很大。如果会话(和事务)范围尽可能的小,那么您遇到的问题就不会真正出现(实体在持久化上下文中保留太长时间)。
你在做批处理吗?如果是,则将批处理工作划分为较小的事务或会话交互可能是一种方法

2ic8powd

2ic8powd2#

作为一个一般的经验法则(从我这里),不要对JPA实体使用@Cacheable,这几乎总是会导致令人惊讶的结果/副作用。
想象以下

public interface SampleRepository extends JpaRepository<Sample, String> {
  
  @Cacheable
  Optional<Sample> findById(String id);

  @Cacheable
  Optional<Sample> findByName(String name);

}

现在,当使用findById方法检索Sample并更改其某些属性时,它最终将被持久化。现在,findById缓存有一个更新的Sample示例。
现在,如果findByName缓存没有与将要添加的Sample实体相同的Sample实体,则没有问题,但是如果它确实具有相同的Sample实体,则不会有更新的记录。即使它引用相同的数据,它也不会引用相同的Sample示例。
这将导致惊人的结果。当然,你可以这样做,当你调用save(这是不需要的),它将销毁所有缓存,但这种挫败缓存的目的。其次,如果有人不调用保存,因为它是一个托管实体,它将自动持久化。
因此,与其在这里使用@Cacheable,不如使用JPA提供程序的二级缓存,可能是Hibernate。它会照顾所有这些事情。

相关问题