Mamy pewna zmapowana klase, ktora sama w sobie nie jest dosc spora, ale posiada pare zmapowanych kolekcji. Mamy 2 use casy:
- pobieranie calego obiektu wraz z kolekcjami zeby pokazac detale, wylistowac wszystkie kolekcje itp
- wyszukiwanie - pokazujemy tylko obiekty ktore spelniaja kryteria, i tylke podstawowe dane; po kliknieciu na element z wyszukanej listy idziemy do detali, czyli pkt. 1
W tej chwili jest to zrobione tak, ze na ta sama tabele sa 2 mapowania, jedno ktore ma w sobie wszystkie kolekcje itp. (do detali) i jedno (read only) ktore pobiera tylko czesc danych (do widoku master w liscie wyszukiwania). Niby dziala, ale nie podoba mi sie pare rzeczy, przede wszystkim to ze uzywany jest 2nd level cache, i wszysko sie spierdolilo. Taki use case:
- wyszukujemy liste i dostajemy klikamy w jakis obiekt, ktory ma status A
- w widoku detali zmieniamy status na B, zapisujemy
- znowu szukamy na podstawie tych samych kryteriow, i dostajemy ten sam obiekt, ale ze starym statusem.
Problemu szukalem dzisiaj caly dzien (nie ja pisalem ten system i go nie znam, koles ktory pisze nie ma wiekszego pojecia i nie umie opdowiadac na pytania) i znalazlem: otoz, uzywamy ehcache i pierwsze zapytanie jest do encji dajmy na to SearchDTO (a wiec taki ma klucz), gdy zapisujemy zmieniamy jednak obiekt klasy FullWypas, i on jest updatowany w cache, a gdy nastepnie szukamy, zwracane sa zcachowane wyniki z poprzedniego zapytania, i nie sa sprawdzane z baza poniewaz zapis dokonal inwalidacji innego regionu! Myslalem ze mnie krew zaleje, ale ok. Naprawilem to tak ze po akcjach ktore mutuja obiekty FullWypas dokonywana jest operacja evict(SearchDTO, <id instancji FullWypas>) i wszyskto teraz dziala. Nie podoba mi sie to rozwiazanie.
Ja bym wolal zrobic tak, zeby byla tylko 1 zmapowana encja, ktora wszyskie relacje ma lazy, i wyszukiwanie zwraca tylko te podstawowe dane (kolekcje nie beda inicjalizowane, wiec nie beda pobierane dane*). Gdy idziemy do widoku detali, pobieramy wszystkie dane razem z kolekcjami za pomoca hql z fetch join, wzglednie po pobraniu wywolujemy size() lub iterator() na kazdej kolekcji zeby ja zainicjalizowac i doladowac (wzglednie, Hibernate.initialize()). Co o tym myslicie? Jak sie takie cos poprawnie implementuje? Macie jakies inne pomysly?
- Do renderowania detali potrzebujemy wszystkich kolekcji itp., poniewaz w momencie renderingu strony sesja hibernate juz jest zamknieta i nie mozna sobie doladowac na zawolanie. Uzywamy wicket, i podobno tam sie tak robi, ale moze mi ktos powie jak to zrobic inaczej? OpenSessionInView nie zadziala tutaj.