You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot+Hibernate更新实体后返回脏数据问题求助

Spring Boot原生查询更新后查询返回过时数据问题

在Spring Boot应用中遇到了脏数据问题:使用原生查询更新实体后,立即查询会返回过时数据。经调试确认数据库已更新,但查询仍返回旧值。

相关代码

邮件状态服务类

public class EsignEmailStateService {
    private final CurrentEsignEmailStateRepository currentEmailStateRepository;
    private final EsignEmailStateFactory emailStateFactory;

    public CurrentEsignEmailState getCurrentState() {
        if(!currentEmailStateRepository.existsByEnvelopeId("contractEnvelope1")){
            currentEmailStateRepository.save(CurrentEsignEmailState.builder()
                    .envelopeId("contractEnvelope1")
                    .build());
        }
        CurrentEsignEmailState stateObject  = currentEmailStateRepository.findByEnvelopeId("contractEnvelope1");
        return stateObject;
    }

    @SneakyThrows
    @Transactional
    public void nextState() {
        CurrentEsignEmailState currentEsignEmailState = getCurrentState();
        EsignEmailState currentState = emailStateFactory.createState(currentEsignEmailState.getCurrentState());
       
        EsignEmailState newCurrentState = currentState.nextState(); 

        saveCurrentState(newCurrentState.getClass().getSimpleName(), currentState.getClass().getSimpleName());
    }

    @Transactional
    private void saveCurrentState(String newstate, String oldstate) {
        currentEmailStateRepository.updateCurrentState("contractEnvelope1", newstate);
    }
}

仓库接口

@Repository
@Cacheable(value = false)
public interface CurrentEsignEmailStateRepository extends JpaRepository<CurrentEsignEmailState, Integer> {

    @Query(value = "SELECT * from current_envelope_email_state where envelope_id = :envelopeId", nativeQuery = true)
    CurrentEsignEmailState findByEnvelopeId(@Param("envelopeId") String contractEnvelopeId);

    @Modifying
    @Query(value = "update current_envelope_email_state set current_state = :state where envelope_id = :envelopeId", nativeQuery = true)
    void updateCurrentState(@Param("envelopeId") String contractEnvelopeId,@Param("state") String state);

    boolean existsByEnvelopeId(String contractEnvelopeId);
}

实体类

public class CurrentEsignEmailState {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    private String envelopeId;

    private String currentState;

    @PrePersist
    public void prePersist(){
        this.currentState = "StartState";
    }//Set message and body here
}

复现情况

已创建可复现该问题的Spring Boot项目,调用API时状态机一次性触发,控制台日志显示更新语句已修改数据库,但查询仍返回旧数据。

已尝试的解决方法及问题

  • 使用entityManager.flush()、entityManager.clear()
  • 在仓库类添加@Cacheable(false)
  • 禁用Hibernate二级缓存

以上方法均未解决问题。若在saveCurrentState方法中添加entityManager.flush()和entityManager.clear(),会抛出如下异常:

org.hibernate.LazyInitializationException: could not initialize proxy [com.example.StaleDataIssue.entities.ContractEnvelope#contractEnvelope1] - no Session

日志显示二级缓存已禁用:

2024-06-06T12:28:28.085+05:30  INFO 9160 --- [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled

恳请各位帮忙解决该问题!

内容的提问来源于stack exchange,提问作者Sherebanu Katheria

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 00:27:17