【问题标题】:Force Hibernate to read database and not return cached entity强制休眠读取数据库并且不返回缓存的实体
【发布时间】:2015-03-10 09:44:23
【问题描述】:

我正在为我的 Web 应用程序使用 Hibernate 和 Spring。

在数据库操作中,Hibernate 缓存实体并在下一个请求中返回它们,而不读取实际的数据库。我知道这将减少数据库的负载并提高性能。

但是当这个应用程序仍在建设中时,我需要在每个请求中从数据库中加载数据(测试原因)。

有没有办法强制读取数据库?

我从这条 log4j 消息中确定了缓存。

Returning cached instance of singleton bean 'HelloController'
DEBUG [http-bio-8080-exec-42] - Last-Modified value for [/myApp/../somePageId.html] is: -1

【问题讨论】:

标签: java spring hibernate caching


【解决方案1】:

session.refresh(entity)entityManager.refresh(entity)(如果您使用 JPA)将为您提供来自 DB 的最新数据。

【讨论】:

  • 我没有使用 JPA。那么我需要将session.get() 更改为session.refresh() 吗?或者是否有办法检查它是否来自缓存。?
  • 不,您应该在session.get() 之后使用session.refresh(),因为它仅适用于附加实体。要检查一个实体是否已经加载,this thread 有一些建议,但没有什么可靠的恕我直言。
  • 这种方法的诀窍是当实体不存在于数据库中,但存在于缓存中时,调用refresh()会抛出org.hibernate.UnresolvableObjectException: No row with the given identifier exists
  • @adamsiemion 是的,这是一个应该注意的事情。
  • 这对于检索多个实体并不令人满意——不会刷新每个实体,只是为每个实体创建一个单独的查询?如果初始查询本身只是绕过缓存,我会更喜欢。我正在做 query.setHint("javax.persistence.cache.retrieveMode", CacheRetrieveMode.BYPASS) ... 但这似乎也不起作用。烦人的缓存!
【解决方案2】:

在新事务中进行读取。

例如:

...
MyDTO myDTO = fetchMyDTOById(daoId);
...
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
private MyDTO fetchMyDTOById(Long dtoId) {
    return repository.findById(dtoId);
}

【讨论】:

    【解决方案3】:
    • 调用刷新实体session.refresh(entity)

    • 打开新会话然后调用session2.get(EntityClass.class,id)它将从数据库中提取实体

          Session session2=sessionFactory.openSession();                  
          EntityClass entity=(EntityClass) session2.get(EntityClass.class, id);
      

    【讨论】:

      【解决方案4】:

      请调用EntityManger.clear()方法,然后根据您的需要调用repository.find()或repository.findOne()从数据库中选择更新的数据。

      @PersistentContext EntityManager em;
      @Autowired EntityReporisitory rep;
      ....
      ....
      @Transactional
      public void method(){
      ....
      ....
      em.clear();// This line will clear the current value of entity
      Entity e = rep.find(example);// In this line data will be loaded freshly from DB
      ....
      ....
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-26
        • 2020-05-19
        • 1970-01-01
        • 2013-12-20
        • 2013-03-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多