Po zdefiniowaniu fasoli jako zakresu prototypowego tworzona jest nowa instancja dla każdego miejsca, w które należy wstrzyknąć. Tak więc każdy DAO otrzyma inną instancję Session, ale wszystkie wywołania metod na DAO będą kończyły się przy użyciu tej samej sesji. Ponieważ sesja nie jest bezpieczna dla wątków, nie powinna być współużytkowana w wielu wątkach, to będzie problem.
W większości sytuacji sesja powinna być zasięgiem transakcji, tj. Nowa sesja jest otwierana po rozpoczęciu transakcji, a następnie zamykana automatycznie po zakończeniu transakcji. W niektórych przypadkach może być konieczne rozszerzenie zakresu na żądanie.
Jeśli chcesz uniknąć używania SessionFactory.currentSession - musisz to zrobić, aby zdefiniować własną implementację zakresu.
To jest coś, co zostało już zaimplementowane w JPA przy użyciu serwerów proxy. W przypadku JPA EntityManager jest wstrzykiwany zamiast EntityManagerFactory. Zamiast @Aucowired jest nowa adnotacja @PersistenceContext. Proxy jest tworzone i wstrzykiwane podczas inicjalizacji. Gdy jakakolwiek metoda zostanie wywołana, proxy zdobędzie aktualną implementację EntityManager (używając czegoś podobnego do SessionFactory.getCurrentSession) i przekazuje ją do niego.
Podobna rzecz może zostać zaimplementowana również w Hibernate, ale dodatkowa złożoność nie jest tego warta. Znacznie łatwiej jest zdefiniować metodę getSession w BaseDAO, która wewnętrznie wywołuje SessionFactory.getCurrentSession(). Dzięki temu kod przy użyciu sesji jest identyczny z sesją iniekcyjną.
Jeden przypadek czytać [doc] (http://docs.jboss.org/hibernate/orm/3.5/javadoc/org/hibernate/Session.html), który mówi 'Jeśli sesja zgłasza wyjątek, transakcja musi być wycofana i sesja wyrzucić. Wewnętrzny stan Sesji może nie być zgodne z bazy danych po wyjątku powodującego powstanie –
Lepiej wstrzyknąć 'javax.persistence.EntityManager' ale za to trzeba domagać się za pomocą JPA zamiast. – Lion