piątek, 3 października 2014

JPA w Spring

Dla Hibernate głównym interfacem na którym wywołujemy np: metodę getCurrentSession() jest interface Session, dla JPA jest to EntityManager."Odpowiednikiem" Hibernatowego SessionFactory jest EntityManagerFactory. W Springu, są dostępne dwie fabryki dla EntityManager'a:   

  •    LocalContainerEntityManagerFactoryBean
  •    LocalEntityManagerFactoryBean

Czym się różnią ? różnią się bebechami, mianowicie tym jak EntityManager jest tworzony, pierwszy zwraca EntityManagera który jest zarządzany przez kontener aplikacji, drugi zaś - zwraca EntityManagera który jest zarządzany przez aplikacje. Dla nas jednak - to co dzieje się pod spodem, jest totalnie bez znaczenia.

Skonfigurujmy sobie obie fabryki: 

LocalEntityManager:

Czym jest persistenceUnitName ? jest nazwą persistence unit(nie wiem jak to po polsku można przetłumaczyć) który znajduje się w persistence descriptorze(w folderze META-INF), o co chodzi z tym całym plikiem, można dowiedzieć się np: tutaj Jeżeli nie chce nam się bawić w tworzenie descriptora, zainteresuj się czytelniku drugim sposobem pobierania EntityManager'a.

LocalContainerEntityManager

Tutaj, EntityManagerFactory jest tworzony używając informacji zapewnionych przez kontener, w naszym przypadku jest to Spring, dzięki temu wszystkie informacje mogą być zawarte w contexcie aplikacji(application-context.xml).
Oto i nasz LocalContainerEntityManagerFactoryBean: oraz JpaVendorAdapter: Jeżeli Spring zaatakuje Was błędami w stylu: Failed to determine Hibernate PersistenceProvider należy dodać do pom.xml, zależność dla:

Hibernate w Spring'u

Hibernate

Głównym interfacem który pozwala nam na komunikacje między Hibernatem i Javą jest hibernatowy Session- udostępnia nam np: takie metody jak save(), get(), flush() . Także pierwszą rzeczą którą będziemy musieli zrobić to pobranie referencji do obiektu org.hibernate.session - Dostaniemy ją prosząc o to hibernatowy interface SessionFactory - a ten ostatecznie zdobędziemy poprzez jedną z springowych fabryk.

Dla Spring 3 - będą to np:

 - AnnotationSessionFactoryBean
 - LocalSessionFactoryBean

Główna różnicą między tymi fabrykami jest fakt, że AnnotationSessionFactoryBean przyjmuje parametr "packagesToScan" któremu podajemy(jak nazwa wskazuje) package z naszymi Encjami - oznaczonymi przy pomocy adnotacji(@Entity) - wszystkie te encje zostaną zeskanowane :)  LocalSessionFactoryBean przyjmie po prostu mappingResources z wypisanymi klasami.

Prosta konfiguracja bean'a LocalSessionFactoryBean
Oraz prosta konfiguracja dla AnnotationSessionFactoryBean

No i oczywiście, potrzebujemy jeszcze referencji do jakiegoś dataSource, może to być np: BasicDataSource od apacha, do pom.xml wystarczy dodać dependency dla: oraz dataSource:

Dla Spring 4:

W spring4 sprawa jest trochę postrza - podczas tworzenia LocalSessionFactoryBean możemy podać ... packagesToScan. Reszta jest analogiczna.