JPA jak to zoptymalizować ?

0

Cześć, sprawa wygląda tak: mam dwie encje - User i Event, gdzie w klasie Event mam referencję do listy Userów:

class Event {
//
	@ManyToMany
	private List<User> users = new ArrayList();
//
}

Napisałem sobie w serwisie metodę do dodawania Userów do danego Eventu, ale widzę, że idzie mi tu aż 5 zapytań SQL co wydaje mi się wysoce nieoptymalne. Oto kod:

@Override
    public Event addUserToEvent(String email, long id) {
        User user = usersService.getUserByMail(email);
        Event event = getEventWithId(id);

        if(isUserParticipantOfEvent(user, event)) return event;

        event.getUsers().add(user);
        return eventsDAO.save(event);
    }

    private boolean isUserParticipantOfEvent(User user, Event event) {
        for(User u : event.getUsers()) {
            if(u.getId() == user.getId()) {
                return true;
            }
        }

        return false;
    }

Myślałem o jakiś customowych query może, ale to mój pierwszy projekt w Springu i jeszcze troszkę po omacku się poruszam.

0

Jakich 5 wklej

0

Przepraszam, 4 idą:

Hibernate: select user0_.id as id1_2_, user0_.email as email2_2_, user0_.firstName as firstNam3_2_, user0_.password as password4_2_, user0_.phoneNumber as phoneNum5_2_, user0_.surname as surname6_2_ from User user0_ where user0_.email=?
Hibernate: select event0_.id as id1_0_, event0_.description as descript2_0_, event0_.title as title3_0_ from Event event0_ where event0_.id=?
Hibernate: select users0_.Event_id as Event_id1_1_0_, users0_.users_id as users_id2_1_0_, user1_.id as id1_2_1_, user1_.email as email2_2_1_, user1_.firstName as firstNam3_2_1_, user1_.password as password4_2_1_, user1_.phoneNumber as phoneNum5_2_1_, user1_.surname as surname6_2_1_ from Event_User users0_ inner join User user1_ on users0_.users_id=user1_.id where users0_.Event_id=?
Hibernate: insert into Event_User (Event_id, users_id) values (?, ?)

0

Jest troche tego to popraway :)
Po 1 generalnie najpierw poczytaj o JPA zanim zaczniesz stosować. Zwracanie encji przez obiekt serwisowy najlepszym pomysłem nie jest, głównie przez sposób zarządzania transakcjami.
Po 2 Nie powinno stosować się List tylko Set. Zwłaszcza że Hibernate nie korzysta z ArrayList tylko ma swoje kolekcje. Listy w zwiazak wiele-do-jednego albo wiele-wiele są złe, listy mogą być tylko ew. zwracane jako wynik zapytania.
Po 3 DAO? Nie korzystasz ze Spring Data JPA?

1

Przecież ta transakcja wymaga właśnie 4 zapytań.
Ja bym się tak specjalnie tym nie przejmował - pracowałem z ze stronami www które robiły po kilkaset zapytań na jedno renderowanie strony.
Te dane będziesz miał częściowo w cache, więc nie powinno to być takie straszne.
Jak będziesz dodawał tysiące użytkowników naraz do eventu w jednej transakcji to pewnie trzeba będzie przerobić.

0

Dziękuję bardzo za odpowiedzii

@scibi92
Co mam zatem zwracać zamiast encji ? Nigdy się nie spotkałem z tym, żeby tak nie robić - masz więcej info gdzieś o tym do poczytania ? Pewnie, że używam spring data - ale przecież tam musimy rozszerzyć JpaRepository (albo CrudRepository) no nie ? I to tam właśnie wstrzykuję.

0

Nie no generalnie powienieneś zwracać encje jak chcesz jednego rezultatu, choć według mnie Optional najlepiej . W przypadku gdy pobierasz sporą listę której obiekty też mają kolecję do innej encji z której chcesz skorzystać (np. User ma Set<Order>) to polecam skorzystać z FETCH JOIN
Ja korzystałem z tego ostatnio : http://helion.pl/ksiazki/java-persistence-programowanie-aplikacji-bazodanowych-w-hibernate-wydanie-ii-christian-bauer-gavin-king-gary-gregory,javpe2.htm ale sporo tego jest :D

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