如何在单次DB调用中记录PTax请求与响应至审计表?
解决方案:通过深拷贝保留请求快照,实现单次DB插入
我之前也碰到过类似的对象引用坑——你现在的问题核心是**pTaxRequest = pTax只是复制了对象引用,并非创建新实例**,所以后续调用updateTax()修改pTax时,pTaxRequest会跟着同步变化,最终请求和响应的记录完全一致。要实现单次DB调用完成审计数据插入,关键是在更新前先保留请求对象的独立快照。
具体实现步骤:
- 深拷贝请求对象:在调用
updateTax()前,把当前未完全赋值的pTax复制成一个独立的新对象,确保后续更新操作不会影响请求快照。 - 单次插入审计数据:将请求快照、更新后的响应对象,以及请求/响应时间一起传入Mapper的单次插入方法。
代码示例(三种深拷贝方式可选)
方式1:手动复制字段(适合字段少的场景)
for(PTax pTax : pFaxTran.getPTaxList()){ // 手动复制当前pTax的所有字段,创建请求快照 PTax pTaxRequest = new PTax(); pTaxRequest.setId(pTax.getId()); pTaxRequest.setTaxCode(pTax.getTaxCode()); // 把PTax的其他初始字段逐一复制... // 执行更新,得到全字段赋值的响应对象 pTax = updateTax(pTax); // 单次DB调用插入审计数据 pTaxMapper.insertPTax(startTime, endTime, pTaxRequest, pTax); }
方式2:用Spring BeanUtils做浅拷贝(适合无嵌套对象的场景)
如果PTax没有嵌套对象,用Spring的BeanUtils可以快速完成拷贝:
import org.springframework.beans.BeanUtils; for(PTax pTax : pFaxTran.getPTaxList()){ // 浅拷贝创建请求快照 PTax pTaxRequest = new PTax(); BeanUtils.copyProperties(pTax, pTaxRequest); // 更新得到响应对象 pTax = updateTax(pTax); // 单次插入 pTaxMapper.insertPTax(startTime, endTime, pTaxRequest, pTax); }
方式3:序列化反序列化做深拷贝(适合有嵌套对象的场景)
如果PTax包含嵌套对象(比如内部有List或自定义对象),浅拷贝会导致嵌套对象还是共用引用,这时候用序列化反序列化做彻底的深拷贝:
import com.fasterxml.jackson.databind.ObjectMapper; for(PTax pTax : pFaxTran.getPTaxList()){ // 深拷贝创建请求快照 ObjectMapper mapper = new ObjectMapper(); PTax pTaxRequest = mapper.readValue(mapper.writeValueAsString(pTax), PTax.class); // 更新得到响应对象 pTax = updateTax(pTax); // 单次插入 pTaxMapper.insertPTax(startTime, endTime, pTaxRequest, pTax); }
关键注意点
- 确保你的
pTaxMapper.insertPTax方法支持接收两个PTax参数,并且能正确映射到审计表的请求字段(比如request_tax_code)和响应字段(比如response_tax_code)。 - 如果用序列化反序列化,要确保PTax的所有字段都支持Jackson序列化(比如没有未公开的字段,或者添加了
@JsonProperty注解)。
内容的提问来源于stack exchange,提问作者Geek
相关产品推荐
相关产品推荐

