简体   繁体   中英

How to avoid redundant data (list fetching) in JPA One To Many mapping (Two One to Many relation in same model)?

I have three Model. BookingDetail have One To Many relation to both LookupFoodItem and LookupFacility model.In my database there is 4 LookupFacility record and 4 LookupFoodItem record. When I'm fetching BookingDetail one record there should be 4 LookupFoodItem record but I found 16 record which is redundant.How can I solve this problem to get only real record not redundant data?

public class BookingDetail {
      @OneToMany(mappedBy = "bookingDetail", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
      public List<LookupFacility> lookupFacilities;
      @OneToMany(mappedBy = "bookingDetail", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
      public List<LookupFoodItem> lookupFoodItems;
}

public class LookupFacility {
      @ManyToOne
      @JoinColumn(name="booking_details_id")
      BookingDetail bookingDetail;
}

public class LookupFoodItem{
      @ManyToOne
      @JoinColumn(name="booking_details_id")
      BookingDetail bookingDetail;
}

When I'm fetching BookingDetail information from database using JPA it's giving me redundant data like this

LookupFoodItem{id=40, name='Beef ', price=120.0}
LookupFoodItem{id=41, name='Polao', price=300.0}
LookupFoodItem{id=42, name='Crab Fry', price=299.0}
LookupFoodItem{id=43, name='Chicken Soup', price=100.0}
LookupFoodItem{id=40, name='Beef ', price=120.0}
LookupFoodItem{id=41, name='Polao', price=300.0}
LookupFoodItem{id=42, name='Crab Fry', price=299.0}
LookupFoodItem{id=43, name='Chicken Soup', price=100.0}
LookupFoodItem{id=40, name='Beef ', price=120.0}
LookupFoodItem{id=41, name='Polao', price=300.0}
LookupFoodItem{id=42, name='Crab Fry', price=299.0}
LookupFoodItem{id=43, name='Chicken Soup', price=100.0}
LookupFoodItem{id=40, name='Beef ', price=120.0}
LookupFoodItem{id=41, name='Polao', price=300.0}
LookupFoodItem{id=42, name='Crab Fry', price=299.0}
LookupFoodItem{id=43, name='Chicken Soup', price=100.0}

There is no relation between LookupFoodItem and LookupFacilities.

Not sure if you are using LOMBOK or actually missing the getters and setter so I added it here.

Used Set instead of List and changed the fetching to Lazy. This is from one of my working solutions. Hope this helps.

Feel free to change the annotations as needed For more details this has some info

public class BookingDetail {
private Set<LookupFacility> lookupFacilities = new HashSet<LookupFacility>();
private Set<LookupFoodItem> lookupFoodItems = new HashSet<LookupFoodItem>();
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "bookingDetail", cascade = CascadeType.ALL, orphanRemoval = true)
    @Fetch(FetchMode.SUBSELECT)
    public Set<LookupFacility> getLookupFacilities() {
        return lookupFacilities;
    }

    public void setLookupFacilities(final Set<LookupFacility> lookupFacilities) {
        this.lookupFacilities = lookupFacilities;
    }


    @OneToMany(fetch = FetchType.LAZY, mappedBy = "bookingDetail", cascade = CascadeType.ALL, orphanRemoval = true)
    @Fetch(FetchMode.SUBSELECT)
    public Set<LookupFoodItem> getLookupFoodItems() {
        return lookupFoodItems;
    }

    public void setLookupFoodItems(final Set<LookupFoodItem> lookupFoodItems) {
        this.lookupFoodItems = lookupFoodItems;
    }
}

And for class LookupFacility and LookupFoodItem us this

private BookingDetail  bookingDetail;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "booking_details_id")
public BookingDetail getBookingDetail() {
        return bookingDetail;
}

public void setBookingDetail(BookingDetail bookingDetail) {
        this.bookingDetail = bookingDetail;
}

If you intend not to fetch records without loading all other relations, i all advice you add fetchType.LAZY to your relationship mapping and also include this json ignore @JsonIgnore so as to solve data loading initialization error at runtime.

See example below

@JsonIgnore
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "booking_details_id")
private BookingDetail  bookingDetail;

With this approach, you should be good to go. I hope this help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM