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
相关产品推荐
相关产品推荐

