JSPWiki logo
Strona główna
Zbieranina
Serwisy
Porady
Projekty
Humor sektora IT
TODO
Nowości
Ostatnie zmiany
Kontakt

Find pages
Unused pages
Undefined pages
Page Index

Set your name in
UserPreferences

Edit this page


Referenced by
News_blogentry_15110...
Projekty




JSPWiki v2.2.33


Hibernate Tools


Hibernate Tools

Istnieje wiele bibliotek do pracy z Hibernate, każda ma swoje zady i walety. Choćby taki Spring - super sprawa, ale jaki duży za to... Czasami potrzeba coś małego, własnego (z naciskiem na to drugie...). Potrzeba matką wynalazców jednak, więc przy okazji jednego projektu powstał i poniższy.

Jakie miałem potrzeby

Miałem kod który mógł być wykonywany zarówno jako aplikacja webowa jak i aplikacja serwerowa dostępna poprzez RMI. W aplikacjach webowych zwykle stosuje się wzorzec OpenSessionInView (jedna sesja Hibernate na cały request klienta). W aplikacjach serwerowych zwykle otwiera się sesję na każde wywołanie metody (chyba, że kod bierze udział w jakiejś większej transakcji, EJB chociażby).

Dodatkowo musiałem też opracować mechanizm pozwalający na przepisanie obiektów zwracanych przez Hibernate (zawierających odwołania lazy loading) do postaci akceptowanej w wyższych warstwach, bez dostępu do sesji Hibernate. Z kolei gdy aplikacja pracowała w wersji dwuwarstwowej takie przepisywanie nie było konieczne.

Potrzebowałem sposobu aby w elegancki i prosty sposób móc przełączać zachowanie kodu pomiędzy takimi przypadkami.

Rozwiązanie

Za dostarczanie poprawnego obiektu Session odpowiedzialne są implementacje interfejsu SessionProvider. Istnieją dwie domyślne implementacje: jedna zwracająca za każdym razem nową sesję (SessionFactory.openSession()) oraz druga zwracająca bieżącą sesję, związaną z aktualnym wątkiem (SessionFactory.getCurrentSession()).

Całą logikę interakcji z Hibernate zawieramy w instancjach abstrakcyjnej klasy Command - zwykle realizowane jest to jako klasy anonimowe. Taki 'gotowy' obiekt Command jest następnie przekazywany do wykonania do instancji klasy HibernateTemplate.

Klasa HibernateTemplate pozwala na zdefiniowanie klasy mogącej reagować na odpowiednie zdarzenia w trakcie operacji z bazą danych. Realizowane jest to poprzez implementacje interfejsu SessionInterceptor. Pozwalają one na wstawienie metod wywoływanych przed wywołaniem akcji, po wywołaniu akcji, oraz na samym końcu metody. Zwykle po wykonaniu akcji zatwierdza się transakcję, a w przypadku pracy z sesjami otwieranymi na żądanie, na koniec metody sesję się zamyka. Dostępne są domyślne implementacje ww interfejsu ułatwiające ww zadania.

Jako bonus dostępna jest klasa filtra serwletów realizującego funkcjonalność OpenSessionInView.

Lista zmian

  • 6.12.2006 - poprawa paru błędów, rozbudowa HibernateTemplate
  • 12.11.2006 - rozbudowa klasy HibernateTemplate o usługowe metody ułatwiające pracę

Dokumentacja

  • JavaDoc
  • Diagram klas dostępny jako załącznik do strony (link na dole)

Kody źródłowe

Moduł HibernateTools w repozytorium CVS

Przykłady

Suchy opis jest mało przydatny, poniżej są próbki kodu pokazujące użycie biblioteki.

Na samym początku pracy (w przypadku aplikacji webowej najlepiej zrealizować to w implementacji ServletContextListener) należy oczywiście zainicjalizować Hibernate. Służy do tego celu usługowa klasa HibernateUtil ze swoja metodą getSessionFactory.

Praca w trybie każdorazowego pobierania nowej sesji

HibernateTemplate hibernate = new HibernateTemplate();
hibernate.setSessionProvider(new NewSessionProvider());
hibernate.setSessionInterceptor(new SingleSessionInterceptor());

Object result = hibernate.action(new Command() {
     public Object action() {
         return session.get(MyDomainObject.class, someId);
     }
});

Przykład jest banalny ;-) Ale pokazuje co możemy zrobić dalej. Poprzez prostą podmianę klasy SessionProvider możemy dostosować aplikację do pracy z bieżącymi sesjami wzorca OpenSessionInView.
Poprzez równie prostą zmianę klasy SessionInterceptor możemy zmienić zachowanie aplikacji - np. można wymusić wycofywanie każdej transakcji w razie potrzeby.

Przygotowanie obiektów do przesłania do wyższych warstw
Poniższy przykład pokazuje jak w prosty sposób można przetworzyć obiekty zwrócone przez Hibernate do postaci nadającej się do przesłania do wyższych warstw:

HibernateTemplate hibernate = new HibernateTemplate();
hibernate.setSessionProvider(new NewSessionProvider());
hibernate.setSessionInterceptor(new SingleSessionInterceptor());

DTOAssembler assembler = new GenericAssembler() {
     protected Object assembleElement(Object o) {
          ((MyDomainObject)o).setParent(null);
          return o;
     }
};

Object result = hibernate.action(new AssembledCommand(assembler) {
     public Object action() {
         return session.createQuery("from MyDomainObject").list();
     }
});

Ten równie banalny przykład pokazuje, jak za pomocą implementacji DTOAssembler można automatycznie przepisać obiekty zwrócone przez Hibernate.


Attachments:

hibernate_tools.jar Info on hibernate_tools.jar 19543 bytes
class_diagram.png Info on class_diagram.png 51793 bytes


Go to top   Edit this page   More info...   Attach file...
This page last changed on 07-Dec-2006 12:34:58 GMT by mikolajr.