Hibernate - odtworzenie znullowanych leniwych relacji

Hibernate - odtworzenie znullowanych leniwych relacji
walec51
  • Rejestracja:ponad 16 lat
  • Ostatnio:12 dni
  • Lokalizacja:Poznań
0

Mam mały problem: gdy encje przychodzą mi do servera po komunikacji z klientem (czyli po serializacji i deserializacji) mam znullowane niektóre relacje (te co miały lzy loading ustawione)

Znacie może jakiś sprytny sposób aby żeby je odtworzyć ?

Bo jak zrobię EntityManager.merger i w relacji OneToMany będę miał null to mi wywali wszystkie encje z tej relacji.

Można na przykład samemu stworzyć jakoś pusty PersistantBag (który wstawiłbym w miejsce tych null'i) tak żeby Hibernate go zainicjalizował przy mergu ?


Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0
  1. Nie mozesz ich od razu pobrać przy wyciąganiu z bazy? (nie mówie oczywiście o eager tylko o fetch join przy zapytaniu)
  2. Możesz po prostu "na jana" wyciągnąć sobie te encje z bazy, przypisać do nulli i zrobić merge i powinno banglać. Oczywiście jest to malo wygodne bo dużo ręcznego kombinowania.

"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
walec51
  • Rejestracja:ponad 16 lat
  • Ostatnio:12 dni
  • Lokalizacja:Poznań
0
Shalom napisał(a):
  1. Nie mozesz ich od razu pobrać przy wyciąganiu z bazy? (nie mówie oczywiście o eager tylko o fetch join przy zapytaniu)

Jakim wyciąganiu z bazy ? Chyba nie zrozumiałeś o co mi chodzi - albo ja Ciebie.
Przychodzi do mnie encja z zewnątrz, od klienta, z zmianami. Muszę ją z merge'ować z tą co siedzi w bazie. Nie mogę tego zrobić zanim nie zrobię coś z tymi nullowanymi relacjami.

Shalom napisał(a):
  1. Możesz po prostu "na jana" wyciągnąć sobie te encje z bazy, przypisać do nulli i zrobić merge i powinno banglać. Oczywiście jest to malo wygodne bo dużo ręcznego kombinowania.

No właśnie chyba tak zrobię - tylko się zastanawiałem czy jest jakieś bardziej ogólne rozwiązanie tego problemu.


edytowany 2x, ostatnio: walec51
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
1

Ad.1. Ja rozumiem o czym piszesz, ale jakoś te dane wysłałeś do klienta do pozmieniania. Jak mu wyślesz bez nulli to i wróci bez nulli ;)
Ad.2. Ja o takim nie słyszałem, ale nie jestem w tej dziedzinie wybitnym ekspertem, może ktoś będzie coś więcej wiedział. @Koziołek @Wibowit @wiciu ? :)


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
Wibowit
oj, ja też nie jestem expertem od Hibernate'a :P
walec51
  • Rejestracja:ponad 16 lat
  • Ostatnio:12 dni
  • Lokalizacja:Poznań
0

Ad.1. Jak nie wyśle z nullami to albo dostanę LazyLodaingException podczas serializacji odpowiedzi do klienta albo będę musiał przez sieć wysłać tysiące niepotrzebnych encji :P
Ad.2. Też nic takiego nie widzę - więc robie se własne narzędzie co mi to trochę zautomatyzuje - już tak czy owak zrobiłem własnego liba do konfiguracji Spring Remoting (RMI i Hessian) przy pomocy dwóch adnotacji w Java Config:
https://bitbucket.org/walczak_it/prodoko-base/src/HEAD/prodoko-remoting/src/main/java/com/prodoko/remoting/?at=master
więc to powinno być małym piwem ;)


Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

Alternatywnie można spróbować zmienić "właściciela" relacji na tą drugą stronę (mapped by) i wtedy jak merge napotka nulle to wydaje mi sie że zamiast usuwać uzupełni sobie. Ale to znów nie jest coś co można zastosować zawsze ;)


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 1x, ostatnio: Shalom
0

Troche nie czaje problemu chyba.

  1. Jesli wysylasz encje z nullami ktore po wybraniu z bazy o ile dobrze rozumiem sam wstawiasz, to dostajesz takie encje z powrotem i wiadomo, wszystko jest usuwane. Jak zmieniasz encje hibernatowe w jedna strone (po odczycie) to przy zapisie / mergu musisz je zmienc w druga strone (dodac te 'zgubione' kolekcje). Innej rady nie ma.
  2. Mowisz ze klient moze dostac LazyInitializationException czy jak sie to zwie. Ok, ale z Twoimi zmianami moze dostac NPE. Jesli klient nie dostaje NPE to albo nie uzywa tych kolekcji (w zwiazku z czym nie ma problemu - slij lazy kolekcje) albo testuje != null, co jest ogolnie niezgodne z hibernate poniewaz on kolekcje ma zawsze nie-nullowe.

Jak by nie patrzec, to nadbudowales na hb jakies swoje 'rozszerzenie', ktore jest polowicznie zaimplementowane - nulluje kolekcje przy odczycie, ale nie przywraca ich przed zapisem / mergem. Jesli dalej chcesz ciagnac ta strategie, to chyba bys musial zaimplementowac swojego merga - pobrac znowu encje z bazy, 'nalozyc' na nia zmiany klienta (nie nadpisywac kolekcji ktore sam znullowales!) i ta prawdziwa encje mergowac - wtedy lazy kolekcje pozostana lazy.
Pytanie jak zapamietac ktore kolekcje sa lazy a ktore klient naprawde zmienil - nie wiem jak to jest w Twoim kodzie, moze jest to latwe do odgadniecia, moze nie, ale mozna to zrobic tak, ze w momencie gdy nullujesz kolekcje 'zbierasz' info o tym ktore byly lazy i zapisujesz do jakiegos pola transient w tej encji. Gdy ona wraca do ciebie od klienta, przy twojej wlasnej implementacji merga masz to dodatkowe info dostepne.
Ogolnie beznadziejny pomysl z tym nullowaniem. Klient to kto? Czesc twojej aplikacji? To napraw kod i nie korzystaj z lazy kolekcji. Jesli klient to nie twoj kod ktory jest gdziesz na innym serwerze to i tak slanie encji hibernatowych nie jest moim zdaniem szczesliwym pomyslem.

1

Biblioteka ktora umie mapowac beany ktora kiedys ogladalem sie zwie Dozer (chyba). Tam sa jakies konwencje ale mozna mapowac za pomoca xml (a jakze). Wiec jak bys zrobil jakies DTO i slal to zamiast encji hb to jak by wracalo to moglbys wszystkie propertisy znowu zmapowac do nowo wczytanej ale poprawnej encji hb.

walec51
  • Rejestracja:ponad 16 lat
  • Ostatnio:12 dni
  • Lokalizacja:Poznań
0

Tak, też się natknąłem na Dozer'a - ale staram się uniknąć właśnie jakiś mapowań XML oraz samych DTO.


Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

Ja osobiście mam złe doświadczenia z traktowaniem obiektów encyjnych jako beanów i DTO. Bo potem są właśnie takie cuda na kiju że nagle ci coś znika z bazy tylko dlatego że miałeś transakcje na poziomie serwisu (więc otwartą sesję) a szykując dane do wysłania pousuwałeś jakieś kolekcje żeby nie wysyłać niepotrzebnych danych ;)
A otwarta sesja = automatyczna synchronizacja obiektu encyjnego z bazą ;]


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 1x, ostatnio: Shalom
airborn
  • Rejestracja:prawie 16 lat
  • Ostatnio:prawie 7 lat
  • Postów:274
0

Problem z którym walczysz niedawno na Trójmiejskim JUGu Sławek Sobótka nazwał podejściem "Encja na twarz i pchasz".

Generalnie z moich doświadczeń też powoduje to trochę problemów. Hibernate opakowuje swoje encje w proxy co czasami może doprowadzić do np. nieskończonej rekurencji (ja miałem taki problem przy połączeniu JAX-RSa z HALem). Generalnie dałem sobie spokój z unikaniem DTO i zauważyłem więcej plusów niż minusów.

0

DTO lub obóz alternatywny OpenSessionInView

Shalom
OpenSessionInView się tu nie nadaje bo mówimy tu o serializowanych i deserializowanych obiektach które gdzieś się wysyła i odbiera.
walec51
  • Rejestracja:ponad 16 lat
  • Ostatnio:12 dni
  • Lokalizacja:Poznań
0

Przy serializacji OpenSessionInView mogło by pomóc ale to mam ogarnięte. Przy deserializacji nic nie da.

DTO trochę śmierdzi bo robi dodatkową hierarchię modelu a u mnie w GUI są dwa bardzo ważne komponenty budowane z retrospecji obiektu modelowego.

Piszę właśnie utilitysa co mi encje wyczyści z macków dowolnego liba JPA i znuluje odpowiednie relacje - w ten sposób stanie się DTO bez zmiany klasy - a potem ten sam lib będzie wiedział, które rzeczy przekopiować do encji jak wróci DTO - czyli nie znuluje mi faktycznych relacji. Mamo to oparte na annotatcjach więc w API po stronie klienta widać kontrakt gdzie nulle oznaczają faktyczne nulle a gdzie stanowią ucięcie grafu obiektów.


edytowany 1x, ostatnio: walec51

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.