Java Bean Copy problems found

About antecedents

    Use Java Bean in the course of their work as a receptacle for data daily work. I found such a problem in the course of their work:
    the main business is that for a split order. Orders are divided into the main part and details section, can have more details after the split calculate the total amount of the order rearranged. This specific business complex than the simple part of the problem arising here explained.

Business simulation

    As defined herein class Order, class OrderHead, OrderDetail as Java objects, and define simple properties, as follows:

@Setter
@Getter
class Order {
    private OrderHead orderHead;
    private List<OrderDetail> orderDetails;
}

@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
class OrderHead {
    private String orderId;
    private String productName;
    private String orderMoney;
}

@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
class OrderDetail {
    private String detailId;
    private String detailName;
    private String detailMoney;
}

    Because it involves a variety of ways in specific business split, the split orders here and recalculate the total amount of write separately in two parts. Here the analog amount is greater than 20 in one order, other orders in another, the specific method code:

private void resetMoney(List<Order> result) {
   for (Order order : result) {
       BigDecimal money = new BigDecimal(0);
       for (OrderDetail orderDetail : order.getOrderDetails()) {
           money = money.add(new BigDecimal(Double.valueOf(orderDetail.getDetailMoney())));
       }
       order.getOrderHead().setOrderMoney(String.valueOf(money));
   }
}

private void split(Order order, List<Order> result) {
  	List<OrderDetail> orderDetails = order.getOrderDetails();
    Order order1 = new Order();
    Order order2 = new Order();

    List<OrderDetail> orderDetails1 = new ArrayList<>();
    List<OrderDetail> orderDetails2 = new ArrayList<>();
    for (OrderDetail orderDetail : orderDetails) {
        if (Double.valueOf(orderDetail.getDetailMoney()) >= 20) {
            orderDetails1.add(orderDetail);
        } else {
            orderDetails2.add(orderDetail);
        }
    }
    order1.setOrderDetails(orderDetails1);
    order2.setOrderDetails(orderDetails2);

    order1.setOrderHead(order.getOrderHead());
    order2.setOrderHead(order.getOrderHead());
    result.add(order1);
    result.add(order2);
}

At first glance no problem here, is to split the order details, the main part of the order into two orders are in, but when there is a problem specific tests, test code is as follows:

private static JavaBeanRelation relation = new JavaBeanRelation();

// 需求把 订单 a 中的 明细 拆分,大于20的单独拆分成一个订单,并重新计算head的总金额,得到最后的两个订单
public static void main(String[] args) {
    Order order = new Order();
    OrderDetail detail1 = new OrderDetail("d1", "dname1", "24");
    OrderDetail detail2 = new OrderDetail("d2", "dname2", "25");
    OrderDetail detail3 = new OrderDetail("d3", "dname3", "15");
    OrderDetail detail4 = new OrderDetail("d4", "dname4", "16");
    OrderHead orderHead = new OrderHead("b1", "bname1", "80");

    order.setOrderHead(orderHead);

    List<OrderDetail> orderDetails = new ArrayList<>();
    orderDetails.add(detail1);
    orderDetails.add(detail2);
    orderDetails.add(detail3);
    orderDetails.add(detail4);
    order.setOrderDetails(orderDetails);

    List<Order> result = new ArrayList<>();
    relation.split(order, result);
    relation.resetMoney(result);
    //输出最后结果JsonUtils为序列化工具类
    System.out.println(JsonUtils.getInstance().toJsonString(result));
}

Console output:

[
  {
    "orderDetails": [
      {
        "detailId": "d1",
        "detailMoney": "24",
        "detailName": "dname1"
      },
      {
        "detailId": "d2",
        "detailMoney": "25",
        "detailName": "dname2"
      }
    ],
    "orderHead": {
      "orderId": "b1",
      "orderMoney": "31",
      "productName": "bname1"
    }
  },
  {
    "orderDetails": [
      {
        "detailId": "d3",
        "detailMoney": "15",
        "detailName": "dname3"
      },
      {
        "detailId": "d4",
        "detailMoney": "16",
        "detailName": "dname4"
      }
    ],
    "orderHead": {
      "orderId": "b1",
      "orderMoney": "31",
      "productName": "bname1"
    }
  }
]

    This time there is a problem, the last one is the subject of the order, 15 + 16 = 31, but first how has changed? That is two orders refer to the same object, a time when one of the other changes also changed, here can be replicated OrderHead recalculated in the sort of time, that can be used directly in a split time two objects, I used here is the Spring BeanUtils.copyProperties (Object source, Object target) throws BeansException method, specific split method modified as follows:

private void split(Order order, List<Order> result) {
   List<OrderDetail> orderDetails = order.getOrderDetails();
   Order order1 = new Order();
   Order order2 = new Order();

   List<OrderDetail> orderDetails1 = new ArrayList<>();
   List<OrderDetail> orderDetails2 = new ArrayList<>();
   for (OrderDetail orderDetail : orderDetails) {
       if (Double.valueOf(orderDetail.getDetailMoney()) >= 20) {
           orderDetails1.add(orderDetail);
       } else {
           orderDetails2.add(orderDetail);
       }
   }
   order1.setOrderDetails(orderDetails1);
   order2.setOrderDetails(orderDetails2);

   order1.setOrderHead(order.getOrderHead());

   OrderHead orderHeadCopy = new OrderHead();
   BeanUtils.copyProperties(order.getOrderHead(),orderHeadCopy);
   order2.setOrderHead(orderHeadCopy);

   result.add(order1);
   result.add(order2);
}

     The results obtained after the modification is completed correctly, the details you can use debug view, order after the split can be seen is the same object reference, Cipian not go into details about why NA clone method next article describes.

发布了7 篇原创文章 · 获赞 0 · 访问量 2426

Guess you like

Origin blog.csdn.net/weixin_42798851/article/details/104729845