Q:

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.

A:

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;
}

