Zwykle używam Hibernate w połączeniu z frameworkiem Spring i jego deklaratywnymi możliwościami demarkacji transakcji (np. @Transactional ).
Jak wszyscy wiemy, hibernacja stara się być tak nieinwazyjna i jak najbardziej przejrzysta , jednak okazuje się to nieco trudniejsze w przypadku lazy-loaded
nawiązywania relacji.
Widzę wiele alternatyw projektowych o różnych poziomach przejrzystości.
- Spraw, aby relacje nie były leniwe (np.
fetchType=FetchType.EAGER)
- To wioaluje całą ideę leniwego ładowania.
- Zainicjuj kolekcje przy użyciu
Hibernate.initialize(proxyObj);
- Oznacza to stosunkowo wysokie sprzężenie z DAO
- Chociaż możemy zdefiniować interfejs z
initialize
, inne implementacje nie gwarantują żadnego odpowiednika.
- Dodaj zachowanie transakcji do
Model
samych obiektów trwałych (używając dynamicznego serwera proxy lub@Transactional
)- Nie próbowałem podejścia dynamicznego proxy, chociaż nigdy nie wydawało mi się, że @Transactional działa na samych trwałych obiektach. Prawdopodobnie w związku z tym, że hibernacja działa na serwerze proxy.
- Utrata kontroli podczas rzeczywistych transakcji
- Zapewnij leniwy / nieleniwy interfejs API, np.
loadData()
IloadDataWithDeps()
- Zmusza aplikację do tego, aby wiedziała, kiedy zastosować którą procedurę, ponownie ścisłe połączenie
- Przepełnienie metody,,
loadDataWithA()
....,loadDataWithX()
- Wymuś wyszukiwanie zależności, np. Tylko przez wykonanie
byId()
operacji- Wymaga wielu procedur nie zorientowanych obiektowo, np.
findZzzById(zid)
, A następniegetYyyIds(zid)
zamiastz.getY()
- Przydatne może być pobieranie każdego obiektu w kolekcji jeden po drugim, jeśli między transakcjami występuje duży narzut przetwarzania.
- Wymaga wielu procedur nie zorientowanych obiektowo, np.
- Uczyń część aplikacji @Transactional zamiast tylko DAO
- Możliwe rozważania na temat transakcji zagnieżdżonych
- Wymaga procedur dostosowanych do zarządzania transakcjami (np. Wystarczająco małych)
- Mały wpływ zautomatyzowany, chociaż może skutkować dużymi transakcjami
- Zapewnij DAO dynamiczne profile pobierania , np.
loadData(id, fetchProfile);
- Aplikacje muszą wiedzieć, którego profilu użyć i kiedy
- Typ transakcji AoP, np. Przechwytywanie operacji i wykonywanie transakcji w razie potrzeby
- Wymaga manipulacji kodem bajtowym lub użycia serwera proxy
- Utrata kontroli podczas zawierania transakcji
- Czarna magia, jak zawsze :)
Czy przegapiłem jakąś opcję?
Które podejście preferujesz, próbując zminimalizować wpływ lazy-loaded
relacji na projekt aplikacji?
(Och, przepraszam za WoT )