Как избежать избыточных данных (выборки из списка) в отображении JPA «один ко многим» (отношение «два один ко многим» в одной модели)? - PullRequest
0 голосов
/ 14 марта 2019

У меня три модели. BookingDetail имеет отношение «один ко многим» как к LookupFoodItem, так и к модели LookupFacility. В моей базе данных есть 4 записи LookupFacility и 4 записи LookupFoodItem. Когда я выбираю одну запись BookingDetail, должно быть 4 записи LookupFoodItem, но я нашел 16 записей, которые являются избыточными. Как я могу решить эту проблему, чтобы получить только реальные записи, а не избыточные данные?

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

Когда я получаю информацию BookingDetail из базы данных, используя JPA, это дает мне избыточные данные, подобные этой

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}

Нет никакого отношения между LookupFoodItem и LookupFacilities.

Ответы [ 2 ]

1 голос
/ 14 марта 2019

Не уверен, используете ли вы LOMBOK или действительно отсутствует метод получения и установки, поэтому я добавил его сюда.

Использовал Set вместо List и изменил выборку на Lazy.Это из одного из моих рабочих решений.Надеюсь, что это поможет.

Не стесняйтесь изменять аннотации по мере необходимости. Для более подробной информации это имеет некоторую информацию

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

И для класса LookupFacility и LookupFoodItemнам это

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;
}
0 голосов
/ 14 марта 2019

Если вы не собираетесь извлекать записи без загрузки всех других отношений, я советую вам добавить fetchType.LAZY в ваше отображение отношений и также включить этот json ignore @JsonIgnore, чтобы решить ошибку инициализации загрузки данных во время выполнения.

См. Пример ниже

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

При таком подходе вы должны хорошо идти. Я надеюсь, что это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...