Wstrzykiwanie EntityManager Vs. EntityManagerFactory

Długie pytanie, proszę o cierpliwość.

Używamy Spring+JPA dla aplikacji webowej. Mój zespół debatuje nad wstrzyknięciem EntityManagerFactory w GenericDAO (DAO oparte na generykach coś na liniach dostarczonych przez APPFUSE, nie używamy JpaDaosupport z jakiegoś powodu) nad wstrzyknięciem EntityManager. Używamy "application managed persistence".

Argumentami przeciwko wstrzykiwaniu a EntityManagerFactory jest to, że jest zbyt ciężki i dlatego nie jest wymagany, EntityManager robi to, czego potrzebujemy. Również, jak wiosna stworzy nowy instancja DAO dla każdego żądania sieci web (wątpię w to) nie będzie żadnych problemów ze współbieżnością, ponieważ w tej samej instancji EntityManager jest współdzielona przez dwa wątki.

Argumentem przemawiającym za wstrzyknięciem EFM jest to, że jest to dobra praktyka nad wszystkim, że zawsze dobrze jest mieć uchwyt do fabryki.

Nie jestem pewien, które jest najlepsze podejście, czy ktoś może mnie oświecić?

Author: Bhesh Gurung, 2009-08-21

4 answers

Plusy i minusy wstrzykiwania EntityManagerFactory vs EntityManager są opisane w dokumentach Spring Tutaj , nie jestem pewien, czy mogę to poprawić.

Mówiąc to, są pewne kwestie w twoim pytaniu, które powinny zostać wyjaśnione.

...Wiosna stworzy nową instancję DAO dla każdego żądania internetowego...

To nie jest poprawne. Jeśli DAO jest fasolą wiosenną, to jest singletonem, chyba że skonfigurujesz go w inny sposób za pomocą scope atrybut w definicji fasoli. Tworzenie DAO na każde żądanie byłoby szalone.

Argumentem przemawiającym za wstrzyknięciem EMF jest to, że jest to dobra praktyka nad wszystkimi jego zawsze dobrze mieć uchwyt do fabryka.

Ten argument nie trzyma się kupy. Ogólna dobra praktyka mówi, że obiekt powinien być wstrzykiwany z minimum współpracowników, których potrzebuje do wykonywania swojej pracy.

 50
Author: skaffman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-30 12:50:26

Składam to, co w końcu zebrałem. Z Sekcji " Implementowanie DAOs w oparciu o zwykłe JPA "w źródle odniesienia:

Chociaż instancje EntityManagerFactory są bezpieczne dla wątków, EntityManager instancje nie są. Wstrzykiwany Menedżer JPA EntityManager zachowuje się jak EntityManager pobierany ze środowiska JNDI serwera aplikacji, zgodnie ze specyfikacją JPA. Deleguje wszystkie wezwania do bieżący Menedżer transakcji, JEŚLI ISTNIEJE; w przeciwnym razie się wycofa. do nowo utworzonego Entitymanagera na operację, w efekcie czyniąc jego gwint użytkowania-Bezpieczny.

Oznacza to, że zgodnie ze specyfikacją JPA instancje EntityManager nie są bezpieczne dla wątków, ale jeśli Spring je obsługuje, stają się bezpieczne dla wątków.

Jeśli używasz Springa, lepiej jest wstrzyknąć EntityManagers zamiast EntityManagerFactory.

 23
Author: SB.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-06 20:02:31

Myślę, że zostało to już dobrze omówione, ale tylko dla wzmocnienia kilku punktów.

  • DAO, jeśli jest wstrzykiwany przez sprężynę, jest singleton domyślnie . Musisz jawnie Ustaw zakres na prototyp aby utworzyć nową instancję za każdym razem.

  • The entity manger injected by @PersistenceContext is thread safe .

Mając to na uwadze, miałem pewne problemy z pojedynczym DAO w mojej aplikacji wielowątkowej. skończyłem uczynienie DAO instance bean i to rozwiązało problem. więc chociaż dokumentacja może powiedzieć jedno, prawdopodobnie chcesz dokładnie przetestować swoją aplikację.

Kontynuacja:

Myślę, że częścią mojego problemu jest to, że używam

@PersistenceContext(unitName = "unit",
    type = PersistenceContextType.EXTENDED)

Jeśli używasz PersistenceContextType.Rozszerzony, należy pamiętać, że trzeba, jeśli dobrze rozumiem, ręcznie zamknąć transakcję. Zobacz ten wątek, aby uzyskać więcej informacji.

Inny Kontynuacja:

Używanie instancyjnego DAO jest bardzo złym pomysłem. Każda instancja DAO będzie miała swój własny bufor persistence, a zmiany w jednym buforze nie będą rozpoznawane przez inne fasole DAO. Przepraszam za złą radę.

 9
Author: James McMahon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-29 13:54:04

Odkryłem, że ustawienie adnotacji wiosennej @ repozytorium na naszych DAOs i posiadanie Entitymanagera zarządzanego przez Spring i wstrzykiwanego przez adnotację @ PersistenceContext jest najwygodniejszym sposobem, aby wszystko działało płynnie. Korzystasz z bezpieczeństwa wątku współdzielonego menedżera uprawnień i tłumaczenia WYJĄTKÓW. Domyślnie współdzielony Menedżer EntityManager będzie zarządzał transakcjami, jeśli na przykład połączysz kilka Dao z menedżera. W końcu przekonasz się, że Twoje Dao staną się anemiczny.

 6
Author: Gaël Marziou,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-21 06:44:24