Pobieranie seansu z miejscem i rezerwacją po id rezerwacji

0

Chciałbym pobrać Screening (seans) z Seat (miejscem) i z Booking (rezerwacją) po bookingId. Screening ma relację one-to-many z Seat a Seat one-to-many z Booking (miejsce może mieć wiele rezerwacji, ale tylko jedna moża być aktywna, reszta musi być anulowana).
Napisałem taką metodę, ale dostaje MultipleBagException:

@Query("select s from booking_screening s join fetch s.seats se join fetch se.bookings b where b.id = :bookingId")
Optional<Screening> readByBookingId(@Param("bookingId") Long booking);
1
Karaczan napisał(a):

https://vladmihalcea.com/hibernate-multiplebagfetchexception/

Ale ja używam Spring Data JPA a nie gołego Hibernata

1
Karaczan napisał(a):

https://vladmihalcea.com/spring-data-jpa-multiplebagfetchexception/

Tylko, że ja mam trochę inny case. On tam pokazuje przykład z encją, która ma dwie kolekcje a ja mam te kolekcje zagnieżdżone

1

@Nofenak: s w query jest aliasem więc select s from... jest błędne

1
Nofenak napisał(a):

Tylko, że ja mam trochę inny case. On tam pokazuje przykład z encją, która ma dwie kolekcje a ja mam te kolekcje zagnieżdżone

Szybki (ale niekoniecznie poprawny) sposób to użycie Set zamiast List, tak jak w pierwszym artykule, tyle że trzeba być świadomym tego co jest wyjaśnione pod How NOT to “fix” the Hibernate MultipleBagFetchException.
Problem z takimi zagnieżdżonymi encjami może być taki, że po złączeniu dostaniesz gigantyczny wynik, a co za tym idzie siada wydajność.

0

ProTip który zacząłem stosować od kilku lat i nieziemsko poprawia mi przewidywalność wyników z JPA - odwróć wszystkie @OneToMany na Many-to-One, ale bez dziwnej @ManyToOne tylko po prostu zwykłe private Long BookingId;. A tak poza tym to polecam native sql query xd

0
Pinek napisał(a):

ProTip który zacząłem stosować od kilku lat i nieziemsko poprawia mi przewidywalność wyników z JPA - odwróć wszystkie @OneToMany na Many-to-One, ale bez dziwnej @ManyToOne tylko po prostu zwykłe private Long BookingId;. A tak poza tym to polecam native sql query xd

Potrzebuje @OneToMany do agregatu, żeby logika mi nie wyciekała do serwisu, np. Seat może mieć tylko 1 Booking ze statusem ACTIVE itp.

0
Nofenak napisał(a):

Potrzebuje @OneToMany do agregatu, żeby logika mi nie wyciekała do serwisu, np. Seat może mieć tylko 1 Booking ze statusem ACTIVE itp.

To o czym piszesz to logika domenowa i spoko, ale nie powinna ona w ogóle potrzebować żadnych adnotacji Springowych/Hibernetowych.

1

Najlepiej (imho) jakbyś na początek zrozumiał, że architektura której najpewniej używasz, powodująca wymieszanie logiki z warstwą persystencji, ssie strasznie mocno (że aż nieprzyjemnie) i byś to odseparował (np. w duchu portów i adapterów).

Mając wydzieloną logikę biznesową i zamodelowany seans wraz z siedzeniami problemy z adnotacjami jpa nagle znikają i życie staje się przyjemniejsze.
Na poziomie db jako takim też w sumie nie potrzebujesz mieć żadnych takich relacji, alternatywnie możesz się posługiwać gołymi identyfikatorami zamiast w encjach zagnieżdżać kolekcję.

Te ficzery że encja bazodanowa z powiązanymi kolekcjami gdzie zarządza wszystkim hibernate i nie musisz nawet wołać save były fajne w czasach architektur warstwowych (a przynajmniej wtedy uważano, że to jest fajne). Aktualnie im ta warstwa persystencji jest cieńsza, implementowana możliwie najpóźniej jak się da i w pełni zastępowalna przez alternatywne implementacje (np. na bazie hash mapy w pamięci) tym lepiej dla Ciebie i dla biznesu.

Zrób kilka kroków wstecz, poczytaj co to jest cloudy think i zastanów się jeszcze raz nad sposobem w którym piszesz kod bo sam sobie tworzysz problemy.

0
RequiredNickname napisał(a):

Najlepiej (imho) jakbyś na początek zrozumiał, że architektura której najpewniej używasz, powodująca wymieszanie logiki z warstwą persystencji, ssie strasznie mocno (że aż nieprzyjemnie) i byś to odseparował (np. w duchu portów i adapterów).

Mając wydzieloną logikę biznesową i zamodelowany seans wraz z siedzeniami problemy z adnotacjami jpa nagle znikają i życie staje się przyjemniejsze.
Na poziomie db jako takim też w sumie nie potrzebujesz mieć żadnych takich relacji, alternatywnie możesz się posługiwać gołymi identyfikatorami zamiast w encjach zagnieżdżać kolekcję.

Te ficzery że encja bazodanowa z powiązanymi kolekcjami gdzie zarządza wszystkim hibernate i nie musisz nawet wołać save były fajne w czasach architektur warstwowych (a przynajmniej wtedy uważano, że to jest fajne). Aktualnie im ta warstwa persystencji jest cieńsza, implementowana możliwie najpóźniej jak się da i w pełni zastępowalna przez alternatywne implementacje (np. na bazie hash mapy w pamięci) tym lepiej dla Ciebie i dla biznesu.

Zrób kilka kroków wstecz, poczytaj co to jest cloudy think i zastanów się jeszcze raz nad sposobem w którym piszesz kod bo sam sobie tworzysz problemy.

Mylisz się. Właśnie próbuje dopasować JPA do mojego modelu domenowego a nie na odwrót. To czy rozdzielę obiekty na te domenowe i JPA nie ma większego znaczenia. Wypowiadali się już o tym doświadczeni ludzie np. Kuba Nabrdalik. Tak, czy siak muszę załadować Screening z Seats i z Bookings, tylko problem w tym, żeby zrobić to wydajnie, w jednym, maks dwoma zapytaniami a nie trzema

1 użytkowników online, w tym zalogowanych: 0, gości: 1