Wpis z mikrobloga

#java #programowanie #hibernate #spring
Czy Hibernate zawsze robi automatyczny update pobranych Encji - jeśli tak, to kiedy zamyka sesję?
Czy robi różnice czy pobieram je bezpośrednio poprzez np. EntityManager a automatycznie wygenerowane repozytoria?
  • 13
  • Odpowiedz
  • Otrzymuj powiadomienia
    o nowych komentarzach

Okej znalazłem coś takiego:

By default, Spring Boot applies transaction management at the repository level


Ale co w przypadku lazy obiektów? Otwiera się nowa sesja i po zaciągnięciu reszty zależności zamyka?
  • Odpowiedz
LazyInitializationException


@MiszkaCFC: Tzn, rozumiem że jeśli pobieram wszystko własnoręcznie i zamknę sesję to dostanę exception przy ładowaniu czegoś lazy. Ale wydaje mi się, że w przypadku używania JPA repository mogę dociągnąć pozostałe zależności już z poziomu serwisu - chociaż teoretycznie sesja została zamknięta po wywołaniu metody repo. Jeśli się mylę to idę się wybatożyć.
  • Odpowiedz
@wafel93: Ten wyjątek poleci jeśli transakcja zostanie zamknięta, a Ty będziesz chciał coś dociągnąć. Dlatego znaczenie tutaj ma zasięg transakcji.

A co do pytania ze wpisu - update jest wykonywany pod koniec transakcji, jeśli obiekt jest 'dirty', czyli został zmodyfikowany.
  • Odpowiedz
@MiszkaCFC: Tak, masz rację - ale czy żeby dociągnąć lazy zależności encji, którą pobrałem w serwisie z poziomu @ Repository, muszę otwierać ręcznie transakcję/sesję? Czy pod spodem dzieje się jakaś magia, której nie widać?
  • Odpowiedz
@wafel93: To troszke bardziej skomplikowane. Propertiesy, ktore sa lazy mozesz pobierac dopoki encja jest w stanie "managed", czyli z grubsza dopoki EntityManager jest otwarty. Z poziomu JPA jest to zupelnie niezalezne od transakcji.

Cale zarzadzanie EntityManagerem zazwyczaj zalatwia Spring i najistotniejsze sa 2 mechanizmy:
- @Transactional - jak Spring widzi metode z taka annotacja, to otwiera sobie nowego EntityManagera i kojarzy go z aktualnym watkiem. EntityManager jest zamykany na
  • Odpowiedz
@wafel93: jest jeszcze coś takiego open session view in https://vladmihalcea.com/the-open-session-in-view-anti-pattern/ które domyślnie w spring boocie jest włączone i czasami nawet jeżeli masz zamknietą sesję i pole z lazy fetch typem (pobierany leniwie) to sesja może być stworzona na chwile w widoku(podczas obsługi żądania ogólnie rzecz biorąc) i obiekt zostanie zaciągnięty z bazy bez rzucania wyjątku Lazy...Exception.
  • Odpowiedz
@wykopek12345: @Kresse: ale wałek z tym OpenEntityManagerInViewInterceptor - wiedzialem że coś jest pod spodem jeszcze xD
Czy jego obecność oznacza, że WSZYSTKIE zmiany na encjach beda flushowane na koniec przetwarzania request'a? Czy to nie działa tak, ze jest mozliwość pobrania lazy elementów, ale jakiekolwiek zmiany bez @ Transactional nie sa flush'owane na koniec przetwarzania?
  • Odpowiedz
@wafel93: No wlasnie tak srednio. EntityManager flushuje kiedy uzna to za stosowne, wiec wszystkie zmiany od ostatniego flusha do konca przetwarzania requesta teoretycznie moga zostac stracone (interceptor nie flushuje niczego na koncu xD).
  • Odpowiedz
interceptor nie flushuje niczego na koncu xD


@Kresse: to jest informacja, której szukałem - dzięki wielkie. Bo generalnie używam Boot'a i robie operacje na Encjach w serwisach (zmieniam wartości, ładuje lazy pola) ale finalnie nie zapisują się one w bazie, jeśli nie wymuszę tego poprzez ręczne ustawienie transakcji/sesji.
  • Odpowiedz