Hibernate jako dostawca JPA w samodzielnej aplikacji
Z Jacek Laskowski - Wiki Projektanta Java EE
Trzeba przyznać, że z każdym dniem, kiedy pracuję z Java EE 5, a dokładniej z Java Persistence API (JPA), coraz bardziej urzeka mnie prostota budowy aplikacji z jej (jego?) pomocą. Sądziłem, że "udogodnienia" Java EE 1.4 i migracja ludzi do rozwiązań alternatywnych, głównie do Spring Framework + Hibernate nie wróżą niczego dobrego dla Java EE 5, ale na szczęście się myliłem. I to jak!
Pisałem juz wcześniej o zaletach rozwiązań w Java EE 5 i nie mogę uwierzyć, że są jeszcze tacy, którzy twierdzą, że tych udogodnień jest jeszcze mało. Niebywałe, czego można jeszcze żądać od grupy standaryzującej platformę Java EE, a nawet samego języka Java. Już jest wiele dobrej zabawy, a ma być jeszcze więcej! ;-)
Wróćmy jednak do tematu JPA w wydaniu Hibernate. Jak można było przypuszczać możliwość podmiany implementacji JPA bez wdrażania zmian w samej aplikacji, która z tej technologii korzysta, działa również dla Hibernate EntityManagera (aka Hibernate JPA). Trzeba przyznać, że doświadczenia z TopLinkiem (artykuł Java Persistence API w samodzielnej aplikacji) i Apache OpenJPA (artykuł OpenJPA jako dostawca JPA w samodzielnej aplikacji) były pozytywne, ale mimo wszystko nie były, aż takie jakie doświadczyłem z Hibernate. Czas jaki poświęciłem na każdego z nich to około 1 godziny i w przypadku Oracle TopLink było to pierwsze podejście, więc wszystko było nowe (praktycznie, ponieważ teoretycznie byłem już do tematu przygotowany). Bogatszy w doświadczenia z TopLinkiem pozwoliły mi na uruchomienie projektu z OpenJPA szybciej, ale konieczność instumentowania klas nie wywarła na mnie pozytywnego wrażenia. Co innego Hibernate. W przypadku Hibernate JPA istnieje możliwość zdefiniowania sposobu wykrycia klas podlegających mechanizmowi trwałego zapisu tak, że nie ma konieczności definiowania ich wszystkich po kolei w pliku persistence.xml. Reszta pozostaje bez zmian. Duża prostota korzystania ze specyfikacji JPA z pewnością miała swoje korzenie z sposobie w jaki Hibernate realizował je wcześniej (nie zapominajmy, że grupa rozwijająca Hibernate była niezwykle aktywna w grupie standaryzującej EJB 3.0).
Spójrzmy jak to jest z włączeniem Hibernate EntityManager w naszej przykładowej aplikacji, której tworzenie rozpoczęto w artykule Java Persistence API w samodzielnej aplikacji.
Spis treści |
Uruchomienie Hibernate EntityManager krok po kroku
Konfiguracja biblioteki Hibernate w NetBeans IDE
Jak w każdym środowisku tworzenia aplikacji, tak i w NetBeans IDE należy najpierw zdefiniować bibliotekę zanim zostanie ona użyta.
Pobieramy wersje dystrybucyjne następujących projektów, które wspólnie złożą się na pełną wersję Hibernate JPA gotową do użycia.
- Hibernate Core
- Hibernate EntityManager
- Hibernate Annotations
Wszystkie wymienione projekty dostępne są pod adresem projektu Hibernate.
Po rozpakowaniu w wybranym przez siebie katalogu przystępujemy do definicji biblioteki Hibernate w NB. Rozpoczynamy konfigurację biblioteki od wybrania menu Add Library... w menu węzła Libraries pod prawym klawiszem myszy projektu JpaStandalone.
Wybieramy kolejno - przycisk Manage Libraries... i definiujemy bibliotekę Hibernate z Library Classpath zawierającą wszystkie pliki jar projektów.
Mając zaznaczoną bibliotekę Hibernate wciskamy przycisk Add Library. Otrzymamy widok projektu jak poniżej.
Utworzenie konfiguracji JPA - persistence.xml
Podobnie jak to miało miejsce dla Oracle TopLink czy Apache OpenJPA tak i Hibernate JPA wymaga podania specyficznych parametrów konfiguracyjnych w pliku persistence.xml.
Zmiany pliku konfiguracyjnego polegają na podaniu nowej wartości znacznika provider, który będzie wskazywał tym razem na org.hibernate.ejb.HibernatePersistence. Wymagane jest podanie kilku innych parametrów, co ostatecznie daje następujący plik konfiguracyjny JPA - persistence.xml.
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="JpaStandalonePU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<!--
<class>pl.jaceklaskowski.Pracownik</class>
-->
<properties>
<property name="hibernate.archive.autodetection" value="class, hbm"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.connection.driver_class" value="org.apache.derby.jdbc.ClientDriver"/>
<property name="hibernate.connection.url" value="jdbc:derby://localhost:1527/sample"/>
<property name="hibernate.connection.username" value="app"/>
<property name="hibernate.connection.password" value="app"/>
<property name="hibernate.c3p0.min_size" value="5"/>
<property name="hibernate.c3p0.max_size" value="20"/>
<property name="hibernate.c3p0.timeout" value="300"/>
<property name="hibernate.c3p0.max_statements" value="50"/>
<property name="hibernate.c3p0.idle_test_period" value="3000"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>
Proszę zwrócić uwagę, na wyłączony znacznik class, który wskazuje na klasy uczestniczące w mechanizmie JPA. W przypadku Hibernate, za pomocą parametru hibernate.archive.autodetection definiujemy sposób działania JPA i nie jest konieczne specyfikowanie klas.
Parametry Hibernate JPA powinny być znane osobom pracującym z Hibernate wcześniej, co również znacząco wpłynie na łatwość migracji z rozwiązania opartego wyłącznie o Hibernate na rozwiązanie oparte o JPA z włączonym Hibernate.
Uruchomienie aplikacji
Po wprowadzeniu zmian podchodzimy do uruchomienia aplikacji. Pomni wcześniejszych problemów podczas uruchamiania aplikacji, włączamy najpierw bazę danych, z której skorzysta Hibernate.
I ostatecznie wciskamy przycisk F6, który uruchomi aplikację.
log4j:WARN No appenders could be found for logger (org.hibernate.ejb.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate:
select
pracownik0_.id as id0_0_
from
Pracownik pracownik0_
where
pracownik0_.id=?
Pobrano null
Przypomnę, że z poprzedniego uruchomienia projektu pozostało nam określenie parametru wejściowego. Jeśli usuniemy go poprzez modyfikację właściwości projektu (menu Properties, a następnie Run), wtedy kolejne uruchomienie zakończy się w ten sposób.
log4j:WARN No appenders could be found for logger (org.hibernate.ejb.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate:
insert
into
Pracownik
(id)
values
(?)
Zapisano pl.jaceklaskowski.Pracownik[id=65536]
Kolejna realizacja specyfikacji JPA została przez nas uruchomiona. Teraz pozostaje już tylko zająć się sprawami samej aplikacji od jej strony biznesowej - mechanizm utrwalania danych w bazie danych, dzięki prostocie JPA, mamy już za nami.
W kolejnym podejściu skorzystamy z JPA w połączeniu z aplikacją internetową z JavaServer Faces 1.2. Jak tak lekko pójdzie kolejnym razem, za tydzień Java EE 5, będzie w pełni opanowany, czego i Tobie życzę! ;-)
