【上线复盘】20190329-一个刷新数据的接口是如何导致几十万的订单数据错误

一、业务场景

  本次上线的功能主要是对工单结算进行优化,支持用户使用多张卡,多张优惠券,多张兑换码进行支付。由于之前只支持单张卡,单张优惠券,单张兑换码。所以涉及订单表和订单详情表的表结构修改,新增一些字段,比如记录多张卡的支付数据等。

如订单主表:

-- 订单相关
-- coupon_pay_data [{"couponId":1,"couponFee":1}]
ALTER TABLE saas_order_record ADD COLUMN `coupon_pay_data` json  DEFAULT NULL COMMENT '优惠券抵扣支付数据';
-- card_pay_data [{"cardId":1,"cardType":1,"amount":1,"num":1,"giftNum":1}] cardType 1次卡 2储值卡,
ALTER TABLE saas_order_record ADD COLUMN `card_pay_data` json  DEFAULT NULL COMMENT '会员卡抵扣支付数据';
-- redemption_pay_data [{"redemptionCode":"1","redemptionFee":1}]
ALTER TABLE saas_order_record ADD COLUMN `redemption_pay_data` json  DEFAULT NULL COMMENT '兑换码抵扣支付数据';

  那么针对历史数据,需要维护这些字段。由于无法通过sql直接维护,所有我的同事通过Java代码提供一个接口来耍数据,只要逻辑清楚,实现起来不太难。

二、如何导致数据错误的呢?

1)我们直接看代码:

    @Override
    @Transactional
    public ApiResponse sync(String orderId) {
        //1. 筛选所有订单数据
        Instant time1 = Instant.now();
        List<SaasOrderRecord> saasOrderRecords = getOrderRecords(orderId);
        if (CollectionUtils.isNotEmpty(saasOrderRecords)) {
            saasOrderRecords.parallelStream().forEach(
                    x -> {
                        List<SaasServiceOrderInfo> saasServiceOrderInfos = getOrderServicesByOrderId(x.getId());
                        List<OrderGoods> orderGoods = getOrderGoodsByOrderId(x.getId());
        。。。
        。。。        
    //2.3 redemption_pay_data
    String redemptionPayData = getRedemptionPayData(saasServiceOrderInfos);
    x.setRedemptionPayData(redemptionPayData);
    //2. 更新saas_order_record
    saasOrderRecordDAO.updateByPrimaryKeySelective(x);

从上面的1、2来看,没啥问题。第一步查询出订单,然后set想复制的字段,再更新。

2)我们再看看

        List<SaasOrderRecord> saasOrderRecords = getOrderRecords(orderId);方法实现

 @Override
    public List<SaasOrderRecord> getOrderRecords(String orderId) {
        if (StringUtils.isNotBlank(orderId)) {
            return saasOrderRecordDAO.findOrders(" and id=" + orderId);
        }
        return saasOrderRecordDAO.findOrders("");
    }
@Select(" select id,coupon_id AS couponId,coupon_fee2 AS couponFee2,card_id AS cardId  from saas_order_record where 1=1 and (coupon_id != 0 OR card_id !=0) ${condition}")
    List<SaasOrderRecord> findOrders(@Param("condition") String condition);

我们从sql来看,会发现只查询了部分字段。查询部分字段是推荐的做法,减少了查询数据量,提高处理效率。但是用的全量类SaasOrderRecord,从更新的方法saasOrderRecordDAO.updateByPrimaryKeySelective(x);来看也没什么问题,因为updateByPrimaryKeySelective方法只更新字段值不为null的字段。

3)真正的问题就出现在,不想更新的字段值不为null

  那么我们就会想,sql中没查询的字段不就是null么。那为啥就不为null了呢?

问题就在于SaasOrderRecord类,我们一看这个类就知道了:

package com.xinchan.xcauto.orm.mysql.merchants.domain.entity;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;

/**
 * saas_order_record
 * @author 
 */
public class SaasOrderRecord implements Serializable {
    /**
     * 自增id
     */
    private Long id;

    /**
     * 创建时间
     */
    private Date createdAt = new Date();

    /**
     * 更新时间
     */
    private Date updatedAt = new Date();

    /**
     * 状态
     */
    private Integer status;

    /**
     * 用户id
     */
    private Long uid;

    /**
     * 门店id
     */
    private Integer storeId;

    /**
     * 销售人id
     */
    private Long sellerId;

    /**
     * 操作人id
     */
    private Long operatorId;

    /**
     * 会员卡id
     */
    private Long cardId;

    /**
     * 手机
     */
    private String phone;

    /**
     * 车牌号
     */
    private String carNum;

    /**
     * 订单号
     */
    private String tradeNo;

    /**
     * 订单类型
     */
    private Integer orderType;

    /**
     * 发起方式
     */
    private Integer initType;

    /**
     * 付款时间
     */
    private Date payTime;

    /**
     * 过期时间
     */
    private Long expireIn;

    /**
     * 支付方式
     */
    private Integer payType;

    /**
     * 原总价
     */
    private Long totalFee = 0L;

    /**
     * 实际总价
     */
    private Long actualFee = 0L;

    /**
     * 抵扣金额
     */
    private Long couponFee = 0L;

    /**
     * 赠送金额
     */
    private Long giftFee = 0L;

    /**
     * 原余额
     */
    private Long originalBalance = 0L;

    /**
     * 备注
     */
    private String note;

    /**
     * 微信openid
     */
    private String wxOpenId;

    /**
     * 优惠券id
     */
    private Long couponId;

    /**
     * 优惠券抵扣金额
     */
    private Long couponFee2 = 0L;

    /**
     * 人为指定的优惠金额
     */
    private Long couponFee3 = 0L;

    /**
     * 订单来源
     */
    private Integer src;

    /**
     * 结算状态
     */
    private Integer settleStatus;

    /**
     * 提现状态
     */
    private Integer withdrawStatus;

    /**
     * 提现记录id
     */
    private Long withdrawRecordId;

    /**
     * 结算id
     */
    private Long settleRecordId;

    /**
     * 工单id
     */
    private Long worksheetId;

    /**
     * 手续费
     */
    private Long cost;

    /**
     * 费率
     */
    private BigDecimal rate;

    /**
     * 使用的卡id列表
     */
    private String useCards;

    /**
     * 是否扣卡短信通知 0 否 1 是
     */
    private Boolean ifDeductCardShortNote;

    /**
     * 门店赠送项原价
     */
    private Long storeCouponFee;

    /**
     * 是否使用他人会员卡 0 否 1 是
     */
    private Boolean useOthersCard;

    /**
     * 是否他人代付 0 否 1 是 2未知
     */
    private Integer othersPay;

    /**
     * 工单编号
     */
    private String worksheetNo;

    /**
     * 提现金额
     */
    private Long withdrawFee;

    /**
     * 使用兑换码抵扣原价
     */
    private Integer redemptionFee;

    /**
     * 组合支付数据
     */
    private String groupPayData = "[]";

    /**
     * 优惠券抵扣支付数据
     */
    private String couponPayData = "[]";

    /**
     * 会员卡抵扣支付数据
     */
    private String cardPayData = "[]";

    /**
     * 兑换码抵扣支付数据
     */
    private String redemptionPayData = "[]";

    private static final long serialVersionUID = 1L;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Date getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }

    public Date getUpdatedAt() {
        return updatedAt;
    }

    public void setUpdatedAt(Date updatedAt) {
        this.updatedAt = updatedAt;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public Long getUid() {
        return uid;
    }

    public void setUid(Long uid) {
        this.uid = uid;
    }

    public Integer getStoreId() {
        return storeId;
    }

    public void setStoreId(Integer storeId) {
        this.storeId = storeId;
    }

    public Long getSellerId() {
        return sellerId;
    }

    public void setSellerId(Long sellerId) {
        this.sellerId = sellerId;
    }

    public Long getOperatorId() {
        return operatorId;
    }

    public void setOperatorId(Long operatorId) {
        this.operatorId = operatorId;
    }

    public Long getCardId() {
        return cardId;
    }

    public void setCardId(Long cardId) {
        this.cardId = cardId;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getCarNum() {
        return carNum;
    }

    public void setCarNum(String carNum) {
        this.carNum = carNum;
    }

    public String getTradeNo() {
        return tradeNo;
    }

    public void setTradeNo(String tradeNo) {
        this.tradeNo = tradeNo;
    }

    public Integer getOrderType() {
        return orderType;
    }

    public void setOrderType(Integer orderType) {
        this.orderType = orderType;
    }

    public Integer getInitType() {
        return initType;
    }

    public void setInitType(Integer initType) {
        this.initType = initType;
    }

    public Date getPayTime() {
        return payTime;
    }

    public void setPayTime(Date payTime) {
        this.payTime = payTime;
    }

    public Long getExpireIn() {
        return expireIn;
    }

    public void setExpireIn(Long expireIn) {
        this.expireIn = expireIn;
    }

    public Integer getPayType() {
        return payType;
    }

    public void setPayType(Integer payType) {
        this.payType = payType;
    }

    public Long getTotalFee() {
        return totalFee;
    }

    public void setTotalFee(Long totalFee) {
        this.totalFee = totalFee;
    }

    public Long getActualFee() {
        return actualFee;
    }

    public void setActualFee(Long actualFee) {
        this.actualFee = actualFee;
    }

    public Long getCouponFee() {
        return couponFee;
    }

    public void setCouponFee(Long couponFee) {
        this.couponFee = couponFee;
    }

    public Long getGiftFee() {
        return giftFee;
    }

    public void setGiftFee(Long giftFee) {
        this.giftFee = giftFee;
    }

    public Long getOriginalBalance() {
        return originalBalance;
    }

    public void setOriginalBalance(Long originalBalance) {
        this.originalBalance = originalBalance;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }

    public String getWxOpenId() {
        return wxOpenId;
    }

    public void setWxOpenId(String wxOpenId) {
        this.wxOpenId = wxOpenId;
    }

    public Long getCouponId() {
        return couponId;
    }

    public void setCouponId(Long couponId) {
        this.couponId = couponId;
    }

    public Long getCouponFee2() {
        return couponFee2;
    }

    public void setCouponFee2(Long couponFee2) {
        this.couponFee2 = couponFee2;
    }

    public Long getCouponFee3() {
        return couponFee3;
    }

    public void setCouponFee3(Long couponFee3) {
        this.couponFee3 = couponFee3;
    }

    public Integer getSrc() {
        return src;
    }

    public void setSrc(Integer src) {
        this.src = src;
    }

    public Integer getSettleStatus() {
        return settleStatus;
    }

    public void setSettleStatus(Integer settleStatus) {
        this.settleStatus = settleStatus;
    }

    public Integer getWithdrawStatus() {
        return withdrawStatus;
    }

    public void setWithdrawStatus(Integer withdrawStatus) {
        this.withdrawStatus = withdrawStatus;
    }

    public Long getWithdrawRecordId() {
        return withdrawRecordId;
    }

    public void setWithdrawRecordId(Long withdrawRecordId) {
        this.withdrawRecordId = withdrawRecordId;
    }

    public Long getSettleRecordId() {
        return settleRecordId;
    }

    public void setSettleRecordId(Long settleRecordId) {
        this.settleRecordId = settleRecordId;
    }

    public Long getWorksheetId() {
        return worksheetId;
    }

    public void setWorksheetId(Long worksheetId) {
        this.worksheetId = worksheetId;
    }

    public Long getCost() {
        return cost;
    }

    public void setCost(Long cost) {
        this.cost = cost;
    }

    public BigDecimal getRate() {
        return rate;
    }

    public void setRate(BigDecimal rate) {
        this.rate = rate;
    }

    public String getUseCards() {
        return useCards;
    }

    public void setUseCards(String useCards) {
        this.useCards = useCards;
    }

    public Boolean getIfDeductCardShortNote() {
        return ifDeductCardShortNote;
    }

    public void setIfDeductCardShortNote(Boolean ifDeductCardShortNote) {
        this.ifDeductCardShortNote = ifDeductCardShortNote;
    }

    public Long getStoreCouponFee() {
        return storeCouponFee;
    }

    public void setStoreCouponFee(Long storeCouponFee) {
        this.storeCouponFee = storeCouponFee;
    }

    public Boolean getUseOthersCard() {
        return useOthersCard;
    }

    public void setUseOthersCard(Boolean useOthersCard) {
        this.useOthersCard = useOthersCard;
    }

    public Integer getOthersPay() {
        return othersPay;
    }

    public void setOthersPay(Integer othersPay) {
        this.othersPay = othersPay;
    }

    public String getWorksheetNo() {
        return worksheetNo;
    }

    public void setWorksheetNo(String worksheetNo) {
        this.worksheetNo = worksheetNo;
    }

    public Long getWithdrawFee() {
        return withdrawFee;
    }

    public void setWithdrawFee(Long withdrawFee) {
        this.withdrawFee = withdrawFee;
    }

    public Integer getRedemptionFee() {
        return redemptionFee;
    }

    public void setRedemptionFee(Integer redemptionFee) {
        this.redemptionFee = redemptionFee;
    }

    public String getGroupPayData() {
        return groupPayData;
    }

    public void setGroupPayData(String groupPayData) {
        this.groupPayData = groupPayData;
    }

    public String getCouponPayData() {
        return couponPayData;
    }

    public void setCouponPayData(String couponPayData) {
        this.couponPayData = couponPayData;
    }

    public String getCardPayData() {
        return cardPayData;
    }

    public void setCardPayData(String cardPayData) {
        this.cardPayData = cardPayData;
    }

    public String getRedemptionPayData() {
        return redemptionPayData;
    }

    public void setRedemptionPayData(String redemptionPayData) {
        this.redemptionPayData = redemptionPayData;
    }

    @Override
    public boolean equals(Object that) {
        if (this == that) {
            return true;
        }
        if (that == null) {
            return false;
        }
        if (getClass() != that.getClass()) {
            return false;
        }
        SaasOrderRecord other = (SaasOrderRecord) that;
        return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
            && (this.getCreatedAt() == null ? other.getCreatedAt() == null : this.getCreatedAt().equals(other.getCreatedAt()))
            && (this.getUpdatedAt() == null ? other.getUpdatedAt() == null : this.getUpdatedAt().equals(other.getUpdatedAt()))
            && (this.getStatus() == null ? other.getStatus() == null : this.getStatus().equals(other.getStatus()))
            && (this.getUid() == null ? other.getUid() == null : this.getUid().equals(other.getUid()))
            && (this.getStoreId() == null ? other.getStoreId() == null : this.getStoreId().equals(other.getStoreId()))
            && (this.getSellerId() == null ? other.getSellerId() == null : this.getSellerId().equals(other.getSellerId()))
            && (this.getOperatorId() == null ? other.getOperatorId() == null : this.getOperatorId().equals(other.getOperatorId()))
            && (this.getCardId() == null ? other.getCardId() == null : this.getCardId().equals(other.getCardId()))
            && (this.getPhone() == null ? other.getPhone() == null : this.getPhone().equals(other.getPhone()))
            && (this.getCarNum() == null ? other.getCarNum() == null : this.getCarNum().equals(other.getCarNum()))
            && (this.getTradeNo() == null ? other.getTradeNo() == null : this.getTradeNo().equals(other.getTradeNo()))
            && (this.getOrderType() == null ? other.getOrderType() == null : this.getOrderType().equals(other.getOrderType()))
            && (this.getInitType() == null ? other.getInitType() == null : this.getInitType().equals(other.getInitType()))
            && (this.getPayTime() == null ? other.getPayTime() == null : this.getPayTime().equals(other.getPayTime()))
            && (this.getExpireIn() == null ? other.getExpireIn() == null : this.getExpireIn().equals(other.getExpireIn()))
            && (this.getPayType() == null ? other.getPayType() == null : this.getPayType().equals(other.getPayType()))
            && (this.getTotalFee() == null ? other.getTotalFee() == null : this.getTotalFee().equals(other.getTotalFee()))
            && (this.getActualFee() == null ? other.getActualFee() == null : this.getActualFee().equals(other.getActualFee()))
            && (this.getCouponFee() == null ? other.getCouponFee() == null : this.getCouponFee().equals(other.getCouponFee()))
            && (this.getGiftFee() == null ? other.getGiftFee() == null : this.getGiftFee().equals(other.getGiftFee()))
            && (this.getOriginalBalance() == null ? other.getOriginalBalance() == null : this.getOriginalBalance().equals(other.getOriginalBalance()))
            && (this.getNote() == null ? other.getNote() == null : this.getNote().equals(other.getNote()))
            && (this.getWxOpenId() == null ? other.getWxOpenId() == null : this.getWxOpenId().equals(other.getWxOpenId()))
            && (this.getCouponId() == null ? other.getCouponId() == null : this.getCouponId().equals(other.getCouponId()))
            && (this.getCouponFee2() == null ? other.getCouponFee2() == null : this.getCouponFee2().equals(other.getCouponFee2()))
            && (this.getCouponFee3() == null ? other.getCouponFee3() == null : this.getCouponFee3().equals(other.getCouponFee3()))
            && (this.getSrc() == null ? other.getSrc() == null : this.getSrc().equals(other.getSrc()))
            && (this.getSettleStatus() == null ? other.getSettleStatus() == null : this.getSettleStatus().equals(other.getSettleStatus()))
            && (this.getWithdrawStatus() == null ? other.getWithdrawStatus() == null : this.getWithdrawStatus().equals(other.getWithdrawStatus()))
            && (this.getWithdrawRecordId() == null ? other.getWithdrawRecordId() == null : this.getWithdrawRecordId().equals(other.getWithdrawRecordId()))
            && (this.getSettleRecordId() == null ? other.getSettleRecordId() == null : this.getSettleRecordId().equals(other.getSettleRecordId()))
            && (this.getWorksheetId() == null ? other.getWorksheetId() == null : this.getWorksheetId().equals(other.getWorksheetId()))
            && (this.getCost() == null ? other.getCost() == null : this.getCost().equals(other.getCost()))
            && (this.getRate() == null ? other.getRate() == null : this.getRate().equals(other.getRate()))
            && (this.getUseCards() == null ? other.getUseCards() == null : this.getUseCards().equals(other.getUseCards()))
            && (this.getIfDeductCardShortNote() == null ? other.getIfDeductCardShortNote() == null : this.getIfDeductCardShortNote().equals(other.getIfDeductCardShortNote()))
            && (this.getStoreCouponFee() == null ? other.getStoreCouponFee() == null : this.getStoreCouponFee().equals(other.getStoreCouponFee()))
            && (this.getUseOthersCard() == null ? other.getUseOthersCard() == null : this.getUseOthersCard().equals(other.getUseOthersCard()))
            && (this.getOthersPay() == null ? other.getOthersPay() == null : this.getOthersPay().equals(other.getOthersPay()))
            && (this.getWorksheetNo() == null ? other.getWorksheetNo() == null : this.getWorksheetNo().equals(other.getWorksheetNo()))
            && (this.getWithdrawFee() == null ? other.getWithdrawFee() == null : this.getWithdrawFee().equals(other.getWithdrawFee()))
            && (this.getRedemptionFee() == null ? other.getRedemptionFee() == null : this.getRedemptionFee().equals(other.getRedemptionFee()))
            && (this.getGroupPayData() == null ? other.getGroupPayData() == null : this.getGroupPayData().equals(other.getGroupPayData()))
            && (this.getCouponPayData() == null ? other.getCouponPayData() == null : this.getCouponPayData().equals(other.getCouponPayData()))
            && (this.getCardPayData() == null ? other.getCardPayData() == null : this.getCardPayData().equals(other.getCardPayData()))
            && (this.getRedemptionPayData() == null ? other.getRedemptionPayData() == null : this.getRedemptionPayData().equals(other.getRedemptionPayData()));
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
        result = prime * result + ((getCreatedAt() == null) ? 0 : getCreatedAt().hashCode());
        result = prime * result + ((getUpdatedAt() == null) ? 0 : getUpdatedAt().hashCode());
        result = prime * result + ((getStatus() == null) ? 0 : getStatus().hashCode());
        result = prime * result + ((getUid() == null) ? 0 : getUid().hashCode());
        result = prime * result + ((getStoreId() == null) ? 0 : getStoreId().hashCode());
        result = prime * result + ((getSellerId() == null) ? 0 : getSellerId().hashCode());
        result = prime * result + ((getOperatorId() == null) ? 0 : getOperatorId().hashCode());
        result = prime * result + ((getCardId() == null) ? 0 : getCardId().hashCode());
        result = prime * result + ((getPhone() == null) ? 0 : getPhone().hashCode());
        result = prime * result + ((getCarNum() == null) ? 0 : getCarNum().hashCode());
        result = prime * result + ((getTradeNo() == null) ? 0 : getTradeNo().hashCode());
        result = prime * result + ((getOrderType() == null) ? 0 : getOrderType().hashCode());
        result = prime * result + ((getInitType() == null) ? 0 : getInitType().hashCode());
        result = prime * result + ((getPayTime() == null) ? 0 : getPayTime().hashCode());
        result = prime * result + ((getExpireIn() == null) ? 0 : getExpireIn().hashCode());
        result = prime * result + ((getPayType() == null) ? 0 : getPayType().hashCode());
        result = prime * result + ((getTotalFee() == null) ? 0 : getTotalFee().hashCode());
        result = prime * result + ((getActualFee() == null) ? 0 : getActualFee().hashCode());
        result = prime * result + ((getCouponFee() == null) ? 0 : getCouponFee().hashCode());
        result = prime * result + ((getGiftFee() == null) ? 0 : getGiftFee().hashCode());
        result = prime * result + ((getOriginalBalance() == null) ? 0 : getOriginalBalance().hashCode());
        result = prime * result + ((getNote() == null) ? 0 : getNote().hashCode());
        result = prime * result + ((getWxOpenId() == null) ? 0 : getWxOpenId().hashCode());
        result = prime * result + ((getCouponId() == null) ? 0 : getCouponId().hashCode());
        result = prime * result + ((getCouponFee2() == null) ? 0 : getCouponFee2().hashCode());
        result = prime * result + ((getCouponFee3() == null) ? 0 : getCouponFee3().hashCode());
        result = prime * result + ((getSrc() == null) ? 0 : getSrc().hashCode());
        result = prime * result + ((getSettleStatus() == null) ? 0 : getSettleStatus().hashCode());
        result = prime * result + ((getWithdrawStatus() == null) ? 0 : getWithdrawStatus().hashCode());
        result = prime * result + ((getWithdrawRecordId() == null) ? 0 : getWithdrawRecordId().hashCode());
        result = prime * result + ((getSettleRecordId() == null) ? 0 : getSettleRecordId().hashCode());
        result = prime * result + ((getWorksheetId() == null) ? 0 : getWorksheetId().hashCode());
        result = prime * result + ((getCost() == null) ? 0 : getCost().hashCode());
        result = prime * result + ((getRate() == null) ? 0 : getRate().hashCode());
        result = prime * result + ((getUseCards() == null) ? 0 : getUseCards().hashCode());
        result = prime * result + ((getIfDeductCardShortNote() == null) ? 0 : getIfDeductCardShortNote().hashCode());
        result = prime * result + ((getStoreCouponFee() == null) ? 0 : getStoreCouponFee().hashCode());
        result = prime * result + ((getUseOthersCard() == null) ? 0 : getUseOthersCard().hashCode());
        result = prime * result + ((getOthersPay() == null) ? 0 : getOthersPay().hashCode());
        result = prime * result + ((getWorksheetNo() == null) ? 0 : getWorksheetNo().hashCode());
        result = prime * result + ((getWithdrawFee() == null) ? 0 : getWithdrawFee().hashCode());
        result = prime * result + ((getRedemptionFee() == null) ? 0 : getRedemptionFee().hashCode());
        result = prime * result + ((getGroupPayData() == null) ? 0 : getGroupPayData().hashCode());
        result = prime * result + ((getCouponPayData() == null) ? 0 : getCouponPayData().hashCode());
        result = prime * result + ((getCardPayData() == null) ? 0 : getCardPayData().hashCode());
        result = prime * result + ((getRedemptionPayData() == null) ? 0 : getRedemptionPayData().hashCode());
        return result;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(" [");
        sb.append("Hash = ").append(hashCode());
        sb.append(", id=").append(id);
        sb.append(", createdAt=").append(createdAt);
        sb.append(", updatedAt=").append(updatedAt);
        sb.append(", status=").append(status);
        sb.append(", uid=").append(uid);
        sb.append(", storeId=").append(storeId);
        sb.append(", sellerId=").append(sellerId);
        sb.append(", operatorId=").append(operatorId);
        sb.append(", cardId=").append(cardId);
        sb.append(", phone=").append(phone);
        sb.append(", carNum=").append(carNum);
        sb.append(", tradeNo=").append(tradeNo);
        sb.append(", orderType=").append(orderType);
        sb.append(", initType=").append(initType);
        sb.append(", payTime=").append(payTime);
        sb.append(", expireIn=").append(expireIn);
        sb.append(", payType=").append(payType);
        sb.append(", totalFee=").append(totalFee);
        sb.append(", actualFee=").append(actualFee);
        sb.append(", couponFee=").append(couponFee);
        sb.append(", giftFee=").append(giftFee);
        sb.append(", originalBalance=").append(originalBalance);
        sb.append(", note=").append(note);
        sb.append(", wxOpenId=").append(wxOpenId);
        sb.append(", couponId=").append(couponId);
        sb.append(", couponFee2=").append(couponFee2);
        sb.append(", couponFee3=").append(couponFee3);
        sb.append(", src=").append(src);
        sb.append(", settleStatus=").append(settleStatus);
        sb.append(", withdrawStatus=").append(withdrawStatus);
        sb.append(", withdrawRecordId=").append(withdrawRecordId);
        sb.append(", settleRecordId=").append(settleRecordId);
        sb.append(", worksheetId=").append(worksheetId);
        sb.append(", cost=").append(cost);
        sb.append(", rate=").append(rate);
        sb.append(", useCards=").append(useCards);
        sb.append(", ifDeductCardShortNote=").append(ifDeductCardShortNote);
        sb.append(", storeCouponFee=").append(storeCouponFee);
        sb.append(", useOthersCard=").append(useOthersCard);
        sb.append(", othersPay=").append(othersPay);
        sb.append(", worksheetNo=").append(worksheetNo);
        sb.append(", withdrawFee=").append(withdrawFee);
        sb.append(", redemptionFee=").append(redemptionFee);
        sb.append(", groupPayData=").append(groupPayData);
        sb.append(", couponPayData=").append(couponPayData);
        sb.append(", cardPayData=").append(cardPayData);
        sb.append(", redemptionPayData=").append(redemptionPayData);
        sb.append(", serialVersionUID=").append(serialVersionUID);
        sb.append("]");
        return sb.toString();
    }
}
View Code

好多字段给了默认值。所以就为导致这次给默认值的字段都被更新为默认值了

 /**
     * 创建时间
     */
    private Date createdAt = new Date();

    /**
     * 更新时间
     */
    private Date updatedAt = new Date();
 /**
     * 原总价
     */
    private Long totalFee = 0L;

    /**
     * 实际总价
     */
    private Long actualFee = 0L;

    /**
     * 抵扣金额
     */
    private Long couponFee = 0L;

    /**
     * 赠送金额
     */
    private Long giftFee = 0L;

    /**
     * 原余额
     */
    private Long originalBalance = 0L;
 /**
     * 优惠券抵扣金额
     */
    private Long couponFee2 = 0L;

    /**
     * 人为指定的优惠金额
     */
    private Long couponFee3 = 0L;
 /**
     * 组合支付数据
     */
    private String groupPayData = "[]";

    /**
     * 优惠券抵扣支付数据
     */
    private String couponPayData = "[]";

    /**
     * 会员卡抵扣支付数据
     */
    private String cardPayData = "[]";

    /**
     * 兑换码抵扣支付数据
     */
    private String redemptionPayData = "[]";

三、针对问题的处理方案

1.因为只影响了SaasOrderRecord这一张表,并且创建时间也被new Date()刷新成当前时间,那么我们可以很容易的通过创建时间不同这个条件来修复数据。

所有让运维将上线前备份库中这张表取个其他表名导入到线上库中,通过sql直接修复。

update saas_order_record s, saas_order_record_2019_03_29 c
set s.created_at = c.created_at,
s.updated_at = c.updated_at,
s.total_fee=c.total_fee, 
s.actual_fee=c.actual_fee,
s.coupon_fee=c.coupon_fee,
s.gift_fee=c.gift_fee,
s.original_balance=c.original_balance,
s.coupon_fee2=c.coupon_fee2,
s.coupon_fee3=c.coupon_fee3,
s.group_pay_data=c.group_pay_data
 where s.id=c.id and s.created_at<>c.created_at;

2.将SaasOrderRecord类中的默认值去掉,防止代码中还有类似的代码而出错

3.将刷数据的接口关闭

原文地址:https://www.cnblogs.com/756623607-zhang/p/10629740.html