首页 > 解决方案 > Spring存储库缓存

问题描述

我正在用 Spring 5 和 Hibernate 编写一个应用程序。有一项服务接收处于与当前持久状态不同的状态的实体。它执行一些处理并将实体保存到数据库(使用 Spring CrudRepository)。

public void saveEntity(Entity entity) {
    ProcessingStatus processingStatus = doSomeProcessing(entity);
    if (processingStatus == ProcessingStatus.SUCCESS) {
        entity.setProcessingStatus(ProcessingStatus.SUCCESS);
        repository.save(entity);
    } else {
        Entity originalEntity = repository.findById(entity.getId());
        originalEntity.setProcessingStatus(ProcessingStatus.FAILURE);
        repository.save(originalEntity);
    }
}

因此,如果处理成功,我们只是将实体标记为成功状态并保存它。否则,不应应用新版本实体附带的任何更改。因此,从存储库中检索原始实体,更改其状态,然后保存。

问题是那条线

Entity originalEntity = repository.findById(entity.getId());

实际上检索已修改的对象(可能由 Hibernate 缓存?),而不是数据库中的原始对象。所以originalEntity具有与实体相同的属性集(作为方法参数接收)。在这种情况下检索原始对象的最佳方法是什么?

标签: springhibernatecachingspring-data-jparepository

解决方案


我想这个saveEntity方法用@Transactional.

出于这个原因,即使没有显式存储到 with repository.save(entity),你也有你的更新对象,因为你在同一个休眠会话中。

您可以detach修改实体,然后您将阅读干净的实体(警告!如果您的实体尚未持久化,您将获得null

要分离和实体,您必须PersistenceContext在您的存储库中注入

@Repository
public class EntityRepository {

    @PersistenceContext
    private EntityManager entityManager;

    public void detachOrderItem(Object object) {
        entityManager.detach(object);
    }
}

然后你必须先调用detach findById

} else {

    entityRepository.detach(entity);

    Entity originalEntity = repository.findById(entity.getId());
    originalEntity.setProcessingStatus(ProcessingStatus.FAILURE);
    repository.save(originalEntity);
}

另一个更简单的解决方案可能是用完public void saveEntity(Entity entity)事务(只有嵌套方法可以进行事务)


推荐阅读