【bug制造机】关于Java数组引起的线上bug

private void recycleEx(LevelChangeDO levelChangeRequestDO, LevelPO currentLevelPO) {
        BigDecimal deductExperienceAmt = currentLevelPO.getDeductExperienceAmt();
        List<LevelTransPO> update = Lists.newArrayList();
        List<LevelTransPO> delete = Lists.newArrayList();
        // 构造对象,记录这次明细
        LevelTransPO levelTransDetailPO = levelTransDetailPOS.get(0);
        levelTransPO.setCreatedAt(null);
        levelTransPO.setId(null);
        levelTransPO.setBizNo(。。。);
        levelTransPO.setBizType(。。。);
        levelTransPO.setTotalAmt(currentLevelPO.getDeductExperienceAmt());
        levelTransPO.setRestAmt(。。。);
        levelTransPO.setOperatorDict(。。。);
        levelTransPO.setReason(。。。);
        // 取出所有的正向值,进行抵扣本次扣减值
        for (LevelTransDetailPO levelTransDetail : levelTransDetailPOS) {
            if (levelTransDetail.getTotalAmt().longValue() > deductExperienceAmt.longValue()) {
                levelTransDetail.setRestAmt(levelTransDetail.getTotalAmt().subtract(deductExperienceAmt));
                levelTransDetail.setReturnAmt(deductExperienceAmt);
                update.add(levelTransDetail);
                break;
            } else {
                deductExperienceAmt = deductExperienceAmt.subtract(levelTransDetail.getTotalAmt());
                delete.add(levelTransDetail);
            }
        }
        // 修改正向抵扣的
        levelTransDetailMapper.update(update);
        levelTransDetailMapper.delete(delete);
        // 创建本次明细
        levelTransDetailMapper.create(levelTransPO);

    }

大家好,我是反卷猫,一个杭漂的Java程序员。今天给大家带来的是一期关于Java数组产生的小bug,话不多说我们直接进入正题。

需求描述

用户由于违反的社区的相关条例,被扣除对应的成长值

成长值:用户进行升级的重要依据,比如用户达到1000成长值就升级为白银等级,2000成长值升级为黄金等级。

既然需要扣除成长值,那我们肯定需要获取正向的成长值记录

成长值记录:为了统计用户何时获取(扣减)的成长值,故添加明细表,用来记录用户成长值的变化,总的成长值 = sum(正向可用成长值之和)

获取到了正向的成长值记录后,就需要遍历记录(毕竟可能一条不够减情况,就需要获取多条),直到待扣减的余额为0。

随后能我们就需要修改正向记录的可用额度(levelTransDetailMapper.update(修改的记录)),

同时将本次扣减的额度记录到明细中(levelTransDetailMapper.create(levelTransPO))。

bug出现

// 构造对象,记录这次明细
LevelTransPO levelTransDetailPO = levelTransDetailPOS.get(0);

由于需要创建明细,该模型包含字段又比较多,bug猫呢就准备偷个小懒,直接去除集合中的第一个(前面有判断集合是否为空哈)进行复用,同时还行这个对象中set了一些值。

家人们可以猜猜会出现什么问题哈,请把会出现的问题打在评论区

导致的问题

1、遍历一次就扣减完了???(levelTransPO.setTotalAmt(currentLevelPO.getDeductExperienceAmt());)

2、为啥create的时候报主键重复错误???

发现原因

// 构造对象,记录这次明细
LevelTransPO levelTransDetailPO = levelTransDetailPOS.get(0);

levelTransDetailPOS为List集合,底层是基于数组进行实现的。因为集合中的对象是引用类型levelTransDetailPO是集合中第一个对象的引用,通过修改levelTransDetailPO的属性值,就相当于修改了集合中第一个对象的属性值。

那第二个又是如何产生的呢,是因为取出来的levelTransDetailPO存在id,导致主键冲突了。

解决方案

1、老老实实构造个新的对象

2、使用深复制,将levelTransDetailPOS.get(0)进行深拷贝,但是记得将id set 为null,防止创建的时候导致id冲突(其他唯一字段同样需要重新赋值)。

好嘞,本期分享的bug就到这结束了,欢迎家人们在评论区讨论你们在工作或学习中遇到的bug吧!我们下期再见!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值