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

