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

JPA保存QdCF对象后两实例引用相同致审计无差异求助

问题原因及解决方案

核心原因:JPA一级缓存的一致性维护

你遇到的问题是Spring Data JPA的EntityManager一级缓存导致的:

  • 调用getReferenceById时,EntityManager会返回一个与当前上下文绑定的实体实例(或代理对象),这个实例会被缓存起来。
  • 当你调用save(incoming)时,如果incoming的ID和current的ID相同,EntityManager会判定这是同一个实体,自动将incoming的属性更新到缓存中的current实例上,保证上下文内实体的一致性。
  • 最终savedQdcf和current指向的是同一个对象(或代理背后的同一实例),自然对比不出任何差异。

可行解决方案

  • 方案1:将current脱离EntityManager上下文
    在获取current后,立即调用EntityManager的detach方法,让它脱离缓存,这样后续的save操作不会修改它的属性:

    QdCF current = this.qdcfRepository.getReferenceById(qdcfPresenter.getId());
    this.entityManager.detach(current); // 脱离缓存,不再受JPA上下文维护
    QdCF savedQdcf = this.qdcfRepository.save(incoming);
    Auditoria audit = this.auditoriaMapper.mapToModificacio(savedQdcf, current);
    
  • 方案2:复制current为独立实例
    不要直接使用缓存中的current,而是复制出一个脱离JPA上下文的独立对象,后续用这个副本和saved对象对比:

    QdCF current = this.qdcfRepository.findById(qdcfPresenter.getId()).orElseThrow();
    // 手动拷贝属性或用BeanUtils生成副本
    QdCF currentCopy = new QdCF();
    org.springframework.beans.BeanUtils.copyProperties(current, currentCopy);
    
    QdCF savedQdcf = this.qdcfRepository.save(incoming);
    Auditoria audit = this.auditoriaMapper.mapToModificacio(savedQdcf, currentCopy);
    
  • 方案3:在独立的EntityManager上下文获取current
    可以通过开启新事务、或者使用EntityManagerFactory创建新的EntityManager来获取current,避免和save操作共享同一个缓存上下文。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 06:31:09