@ OneToMany(fetch = FetchType.EAGER), FetchType.EAGER's rapidly loaded BUG that causes queries to duplicate detailed data

The project uses spring data jpa,

After configuring many-to-one and one-to-many table object associations,

Colleagues found that there were two data inquiries from more than one party, and their data IDS were the same.

At first they thought it was Ali's json serialization, because of repeated references, circular references, which led to the BUG.

But he set up fastjson to prohibit duplicate references and circular references, which could not be solved.

Just as I noticed, I went to know about the BUG. At first I thought it was Ali fastjson's BUG.

But when I debug looked at the data, I found that the list had two identical data.

That's when they misconfigure relationships.

//Associated object code:

//One side:

 @OneToMany(fetch = FetchType.EAGER, mappedBy = "trade")
    private List<TcOrder> orderList = new ArrayList<>();


     * Parent order ID
    @Column(name = "trade_id", nullable = true, length = 19)
    private Long tradeId;

    @JoinColumn(name = "trade_id", unique = true, insertable = false, updatable = false)
    @JSONField(serialize = false)
    private TcTrade trade;

//This configures the SQL at query time
        tctrade0_.id as id1_158_0_,
        tctrade0_.account_status as account_2_158_0_,
        tctrade0_.addres_id as addres_i3_158_0_,
        tctrade0_.biz_type as biz_type4_158_0_,
        tctrade0_.buyer_id as buyer_id5_158_0_,
        tctrade0_.buyer_name as buyer_na6_158_0_,
        tctrade0_.buyer_org_id as buyer_or7_158_0_,
        tctrade0_.buyer_type as buyer_ty8_158_0_,
        tctrade0_.cancel_reason as cancel_r9_158_0_,
        tctrade0_.cancel_time as cancel_10_158_0_,
        tctrade0_.cancel_type as cancel_11_158_0_,
        tctrade0_.channel as channel12_158_0_,
        tctrade0_.create_time as create_13_158_0_,
        tctrade0_.customer_id as custome14_158_0_,
        tctrade0_.customer_name as custome15_158_0_,
        tctrade0_.customer_nick_name as custome16_158_0_,
        tctrade0_.dealer_id as dealer_17_158_0_,
        tctrade0_.dealer_name as dealer_18_158_0_,
        tctrade0_.delivery_amount as deliver19_158_0_,
        tctrade0_.delivery_status as deliver20_158_0_,
        tctrade0_.delivery_way as deliver21_158_0_,
        tctrade0_.discount_amount as discoun22_158_0_,
        tctrade0_.fans_id as fans_id23_158_0_,
        tctrade0_.fee_item_amount as fee_ite24_158_0_,
        tctrade0_.follower_id as followe25_158_0_,
        tctrade0_.follower_org_id as followe26_158_0_,
        tctrade0_.goods_amount as goods_a27_158_0_,
        tctrade0_.have_invoice as have_in28_158_0_,
        tctrade0_.hedge_type as hedge_t29_158_0_,
        tctrade0_.income_amount as income_30_158_0_,
        tctrade0_.invoice_id as invoice31_158_0_,
        tctrade0_.invoice_no as invoice32_158_0_,
        tctrade0_.min_send_amount as min_sen33_158_0_,
        tctrade0_.modify_time as modify_34_158_0_,
        tctrade0_.order_type as order_t35_158_0_,
        tctrade0_.org_id as org_id36_158_0_,
        tctrade0_.pay_amount as pay_amo37_158_0_,
        tctrade0_.pay_status as pay_sta38_158_0_,
        tctrade0_.pay_time as pay_tim39_158_0_,
        tctrade0_.payment_id as payment40_158_0_,
        tctrade0_.payment_no as payment41_158_0_,
        tctrade0_.promoter_id as promote42_158_0_,
        tctrade0_.promoter_name as promote43_158_0_,
        tctrade0_.promoter_org_id as promote44_158_0_,
        tctrade0_.promoter_type as promote45_158_0_,
        tctrade0_.refunded_amount as refunde46_158_0_,
        tctrade0_.remark as remark47_158_0_,
        tctrade0_.remind_delivery as remind_48_158_0_,
        tctrade0_.removed as removed49_158_0_,
        tctrade0_.require_deliver_date as require50_158_0_,
        tctrade0_.seller_id as seller_51_158_0_,
        tctrade0_.seller_name as seller_52_158_0_,
        tctrade0_.seller_org_id as seller_53_158_0_,
        tctrade0_.seller_type as seller_54_158_0_,
        tctrade0_.source_id as source_55_158_0_,
        tctrade0_.source_no as source_56_158_0_,
        tctrade0_.staff_id as staff_i57_158_0_,
        tctrade0_.staff_name as staff_n58_158_0_,
        tctrade0_.store_id as store_i59_158_0_,
        tctrade0_.store_name as store_n60_158_0_,
        tctrade0_.total_amount as total_a61_158_0_,
        tctrade0_.trade_img as trade_i62_158_0_,
        tctrade0_.trade_no as trade_n63_158_0_,
        tctrade0_.trade_status as trade_s64_158_0_,
        tctrade0_.uuid as uuid65_158_0_,
        orderlist1_.trade_id as trade_i29_146_1_,
        orderlist1_.id as id1_146_1_,
        orderlist1_.id as id1_146_2_,
        orderlist1_.brand_id as brand_id2_146_2_,
        orderlist1_.brand_name as brand_na3_146_2_,
        orderlist1_.create_time as create_t4_146_2_,
        orderlist1_.customer_id as customer5_146_2_,
        orderlist1_.customer_name as customer6_146_2_,
        orderlist1_.customer_nick_name as customer7_146_2_,
        orderlist1_.dealer_id as dealer_i8_146_2_,
        orderlist1_.dealer_name as dealer_n9_146_2_,
        orderlist1_.delivery_amount as deliver10_146_2_,
        orderlist1_.discount_amount as discoun11_146_2_,
        orderlist1_.express_code as express12_146_2_,
        orderlist1_.express_name as express13_146_2_,
        orderlist1_.express_no as express14_146_2_,
        orderlist1_.fans_id as fans_id15_146_2_,
        orderlist1_.goods_amount as goods_a16_146_2_,
        orderlist1_.income_amount as income_17_146_2_,
        orderlist1_.modify_time as modify_18_146_2_,
        orderlist1_.order_img as order_i19_146_2_,
        orderlist1_.order_no as order_n20_146_2_,
        orderlist1_.order_state as order_s21_146_2_,
        orderlist1_.org_id as org_id22_146_2_,
        orderlist1_.removed as removed23_146_2_,
        orderlist1_.staff_id as staff_i24_146_2_,
        orderlist1_.staff_name as staff_n25_146_2_,
        orderlist1_.store_id as store_i26_146_2_,
        orderlist1_.store_name as store_n27_146_2_,
        orderlist1_.total_amount as total_a28_146_2_,
        orderlist1_.trade_id as trade_i29_146_2_,
        itemlist2_.order_id as order_i24_147_3_,
        itemlist2_.id as id1_147_3_,
        itemlist2_.id as id1_147_4_,
        itemlist2_.actual_price as actual_p2_147_4_,
        itemlist2_.appraise_id as appraise3_147_4_,
        itemlist2_.category_id as category4_147_4_,
        itemlist2_.category_name as category5_147_4_,
        itemlist2_.create_time as create_t6_147_4_,
        itemlist2_.dealer_id as dealer_i7_147_4_,
        itemlist2_.dealer_name as dealer_n8_147_4_,
        itemlist2_.deliver_num as deliver_9_147_4_,
        itemlist2_.deliver_status as deliver10_147_4_,
        itemlist2_.deliver_time as deliver11_147_4_,
        itemlist2_.discount_price as discoun12_147_4_,
        itemlist2_.express_code as express13_147_4_,
        itemlist2_.express_name as express14_147_4_,
        itemlist2_.express_no as express15_147_4_,
        itemlist2_.goods_id as goods_i16_147_4_,
        itemlist2_.goods_no as goods_n17_147_4_,
        itemlist2_.goods_title as goods_t18_147_4_,
        itemlist2_.item_img as item_im19_147_4_,
        itemlist2_.item_state as item_st20_147_4_,
        itemlist2_.item_type as item_ty21_147_4_,
        itemlist2_.modify_time as modify_22_147_4_,
        itemlist2_.num as num23_147_4_,
        itemlist2_.order_id as order_i24_147_4_,
        itemlist2_.original_price as origina25_147_4_,
        itemlist2_.remark as remark26_147_4_,
        itemlist2_.removed as removed27_147_4_,
        itemlist2_.return_num as return_28_147_4_,
        itemlist2_.sale_price as sale_pr29_147_4_,
        itemlist2_.sale_type as sale_ty30_147_4_,
        itemlist2_.share_price as share_p31_147_4_,
        itemlist2_.shipper_id as shipper32_147_4_,
        itemlist2_.shipper_name as shipper33_147_4_,
        itemlist2_.sku_id as sku_id34_147_4_,
        itemlist2_.sku_no as sku_no35_147_4_,
        itemlist2_.source_id as source_36_147_4_,
        itemlist2_.source_item_id as source_37_147_4_,
        itemlist2_.source_no as source_38_147_4_,
        itemlist2_.source_type as source_39_147_4_,
        itemlist2_.specification as specifi40_147_4_,
        itemlist2_.store_id as store_i41_147_4_,
        itemlist2_.store_name as store_n42_147_4_,
        itemlist2_.trade_id as trade_i43_147_4_ 
        tc_trade tctrade0_ 
    left outer join
        tc_order orderlist1_ 
            on tctrade0_.id=orderlist1_.trade_id 
    left outer join
        tc_order_item itemlist2_ 
            on orderlist1_.id=itemlist2_.order_id 

//There are two left join s, which are the detailed data that cause duplication.




Old code, multi-party configuration method is different from my method. If you configure @ManyToOne, normally you don't configure @JoinColumn.

Here, if you remove @JoinColumn, you will report an error again, because the configuration has tradeId, which is duplicated. In that case, you may need to change the code.

It could be BUG.



1. But there are other ways to change it. For example, after the query, check the detailed order data again and repeat the assignment.

2. Changing to lazy loading can solve the problem. Do not use EAGER, but also affect performance.

fetch = FetchType.LAZY

Tags: Programming Spring JSON SQL

Posted on Tue, 08 Oct 2019 04:13:50 -0700 by melbell