Zwracanie zleceń użytkownika

0

Cześć, mam problem, już go wam opisuje,

Musze zrobić metodę zwracająca wszystkie zlecenia w których użytkownik zgłosił swoją kandydaturę, czyli takie w których zalogowany użytkownik widnieje na liście appliedBy.

I teraz tak,
Mam encje ApplicationEntity z wiązaniem:


```@OneToMany
    private List<UserEntity> appliedBy;

I teraz pytanie, jak mogę dowiedzieć się czy mój użytkownik znajduje się na liście z powyższego wiązania?

Dodam, że muszę napisać tą metodę w warstwie serwisu.

2

I teraz pytanie, jak mogę dowiedzieć się czy mój użytkownik znajduje się na liście z powyższego wiązania?

chcesz sprawdzić czy Twój użytkownik znajduje się na liście.. nie wiem jakie masz pola w tej klasie, ale musisz pokombinować ze streami, coś w stylu:

        appliedBy.stream().anyMatch(us -> us.getUserName().equals("Twoj user"));
2

Czyli musisz przeszukać wszystkie listy i zobaczyć, które zawierają danego usera. Spróbuj hqlem -> https://stackoverflow.com/questions/14310146/hql-query-for-searching-one-to-many-relation

Ew. proste query w SQL, które zwróci idki ApplicationEntity (masz je po drugiej stronie jako FK) i potem dociagasz encje, które potrzebujesz po id.

0

Zrobiłem w taki sposób, poproszę o CR i o zdanie czy to wg sens, nie patrzcie, ze użyłem strem, interesuje mnie na razie to żeby działało


```public ApplicationEntity getCurrentUserApplication(AuthenticatedUser user){
        //pobieramy aktualnego użytkownika
        UserEntity currentUser = getCurrentUser(user.getId());
        //wyciągamy z niego email
        String userEmail = currentUser.getEmail();

        //wyciągamy zamówienia użytkownika
        OrderEntity order = orderService.find(user.getId());
        //bierzemy z niego status zamówienia
        OrderState state = order.getOrderState();

        //wyciągamy wszystkie zamówienia
        ApplicationEntity application = (ApplicationEntity) applicationRepository.findAll();
        //sprawdzamy czy user znajduje sie na liscie appliedBy
        boolean appliedBy = application.getAppliedBy().stream().anyMatch(us -> us.getEmail().equals(userEmail));

        //jeśli user znajduje sie na liscie a jego zamowienie jest oznaczone jako enum finished lub delivered zwracamy wszystkie zamowienia
        if((appliedBy == true) && (state.equals(OrderState.FINISHED) || state.equals(OrderState.DELIVERED)){
            return (ApplicationEntity) orderService.findAll();
        }
    }

    public UserEntity getCurrentUser(UUID id){
        return userService.find(id);
    }


ps. jak zwrócić wszystkie zamówienia jeśli w ifie == true?
3

@piotrek2137 To co napisałeś nie przejdzie przez review w żadnej firmie.

A tak jak poniżej nie zadziała? Nie wiem jakiego typu jest id, więc musisz ewentualnie poprawić.

@Query("select a from ApplicationEntity a join a.appliedBy u where u.id = :loggedUserId")
public List<ApplicationEntity> getApplicationsOfUser(@Param("loggedUserId") String loggedUserId)

Edit: Jeżeli chcesz zwrócić tylko informację czy user jest na tej liście to:

@Query("select case when count(*) > 0 then true else false end from ApplicationEntity a join a.appliedBy u where u.id = :loggedUserId")
public boolean isAssignedToApplication(@Param("loggedUserId") String loggedUserId)
1

Kompletnie nie rozumiem sensu wymyślania roweru na nowo :)
Najlepszą praktyką, opcją jest pobranie listy spełniającej wymagania biznesowe zwyczajnym zapytaniem.
Jak już to @Query i JPQL są zakazane, zrób nativeQuery i przemapuj wynik zapytania na obiekt Javy. Czysty SQL zawsze będzie najbardziej wydajny.

SELECT (x.*)
FROM x 
LEFT JOIN y ON x.id = y.foreignKeyId 
WHERE ...

Kod, który wygenerowałeś w komentarzu wyżej może sprawić bardzo dużo problemów w przypadku, gdy informacji w bazie danych przybędzie.
Wtedy osoba, która będzie musiała zoptymalizować ten kod złapie się za głowę co Ty wymyśliłeś :P

5

Klasyczne JPA -> dzielna walka z nieistniejącymi problemami :D jeszcze napisz że w sumie z tego ApplicationEntity interesują cię jakieś 2 pola a nie wszystko co jest w tej tabeli (pewnie jeszcze pojoinowane z innymi tabelami) i już będzie można zakreślić całe JPA bingo.
edit: o lepiej, widzę że ty w ogóle chcesz tylko jednego booleana dostać, to już w ogóle jakiś hardkor się tu dzieje.
To co zrobiłeś teraz to dramat wydajnościowy. Wyrywasz calą bazę i filtrujesz sobie po stronie aplikacji zamiast zrobić proste query.

0

hmmmm. Argument ze zlozonosc niewazna bo listy w 90% przypadkow maja i tak po ~20entry pada :)

0
    @Query("select a from Applicationn a join a.appliedBy u where u.id = :userID")
    List<ApplicationEntity> getUserApplications(@Param("userID") UUID userID);

    List<ApplicationEntity> applications = applicationRepository.getUserApplications(user.getId());
    applications.stream().allMatch(us -> us.equals(OrderState.DELIVERED) || us.equals(OrderState.FINISHED));

    return applications;

a co sądzicie o tym?

2

Na pierwszy rzut oka wyglada ok, ale wklej jakie zapytanie SQL jest generowane

0

@Charles_Ray: orderState, zmieniłem ale teraz mi pokazuje "could not resolve property: orderState",
orderState znajduje się w encji OrderEntity a w ApplicationEntity('applcations' w hql) jest takie wiazanie:

@ManyToOne
private OrderEntity order;

probowalem takie cos jeszcze ale dalej nic

@Query("select a from Applications a join a.appliedBy u, a.order o where u.id = :userID and o.orderState IN ('DELIVERED','FINISHED')")
1

Nie rozumiesz jak to działa. Zmień „o.orderState” na „o.order.state” zakładając ze Order ma pole state. Ja za Ciebie całości nie zrobię, myślmy.

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