最近在做一个项目成本统计的功能,要求计算出“项目总成本”
,springboot在返回响应给前端的过程中,调用了两次“项目总成本”的getTotalCostAmt()
方法,导致算出来的结果翻倍了,当时排查了好一会儿,现在记录一下这个问题,希望对其他人有所帮助,具体是这样的:
首先,项目总成本=【人工成本】+【材料成本】+【设备成本】+【费用成本】+【分包成本】+【其他成本】
所以,我就定义了一个实体:
@Data
@EqualsAndHashCode(callSuper = false)
public class LinkappsProjectCostStatResp implements Serializable {
@ApiModelProperty(value = "总预算")
private BigDecimal totalBudgetAmt = BigDecimal.valueOf(0.00);
@ApiModelProperty(value = "收入合同结算")
private BigDecimal totalIncomeContractSettlementAmt = BigDecimal.valueOf(0.00);
@ApiModelProperty(value = "人工成本")
private BigDecimal totalLaborAmt = BigDecimal.valueOf(0.00);
@ApiModelProperty(value = "材料成本")
private BigDecimal totalMaterialAmt = BigDecimal.valueOf(0.00);
@ApiModelProperty(value = "设备成本")
private BigDecimal totalEquipmentAmt = BigDecimal.valueOf(0.00);
@ApiModelProperty(value = "费用成本")
private BigDecimal totalFeesAmt = BigDecimal.valueOf(0.00);
@ApiModelProperty(value = "分包成本")
private BigDecimal totalSubcontractAmt = BigDecimal.valueOf(0.00);
@ApiModelProperty(value = "其他成本")
private BigDecimal totalOtherCostAmt = BigDecimal.valueOf(0.00);
@ApiModelProperty(value = "总成本:【人工成本】+【材料成本】+【设备成本】+【费用成本】+【分包成本】+【其他成本】。")
private BigDecimal totalCostAmt = BigDecimal.valueOf(0.00);
public BigDecimal getTotalCostAmt() {
//+人工成本
totalCostAmt = totalCostAmt.add(totalLaborAmt);
//+材料成本
totalCostAmt = totalCostAmt.add(totalMaterialAmt);
//+设备成本
totalCostAmt = totalCostAmt.add(totalEquipmentAmt);
//+费用成本
totalCostAmt = totalCostAmt.add(totalFeesAmt);
//+分包成本
totalCostAmt = totalCostAmt.add(totalSubcontractAmt);
//+其他成本
totalCostAmt = totalCostAmt.add(totalOtherCostAmt);
}
}
该实体中,除了totalCostAmt
属性需要临时计算外,其他属性都是直接从数据库查询出来的,所以我单独把totalCostAmt
的getTotalCostAmt()
给放出来了。
通过Postman发请求测试,发现totalCostAmt
的数值是正确结果的2倍,后来跟了代码才知道,springBoot框架在返回数据过程中,会调用两次实体属性的getter方法,第一次进入 getTotalCostAmt()
方法时,totalCostAmt
的初始值是0
,没有问题,但是第二次进入getTotalCostAmt()
,totalCostAmt
的初始值已经不是0
,而是第一次计算之后的正确结果,所以我换掉了以下的写法:
totalCostAmt = totalCostAmt.add(XXXX)
将getTotalCostAmt()
方法改了一下:
public BigDecimal getTotalCostAmt() {
//+人工成本
return totalLaborAmt
//+材料成本
.add(totalMaterialAmt)
//+设备成本
.add(totalEquipmentAmt)
//+费用成本
.add(totalFeesAmt)
//+分包成本
.add(totalSubcontractAmt)
//+其他成本
.add(totalOtherCostAmt);
}