07 marca 2007

Java Persistence - Rozdział 7: Umowy kontenera i dostawcy JPA o instalacji i uruchomieniu

Ale mi się dzisiaj udało z tlumaczeniem! 10-cio stronicowy rozdział 7. zatytułowany w oryginale Container and Provider Contracts for Deployment and Bootstrapping to w moim wolnym tłumaczeniu odpowiada treści umów (kontraktów) kontenera i dostawcy JPA o sposobie instalacji i uruchomieniu aplikacji korzystających z JPA. Wczorajsza lektura o dystrybucji encji to preludium do kontraktów kontenera Java EE i dostawcy JPA dotyczącego instalacji i samego uruchomienia aplikacji JPA. Bardzo techniczny rozdział i szczęśliwie krótki. Przeznaczony wyłącznie dla samych dostawców JPA. Programiści tworzący aplikacje JPA mogą spokojnie ominąć ten rozdział bez żadnej straty (mnie się niestety nie udało ominąć, bo skąd miałem wiedzieć, co w nim będzie bez lektury, nieprawdaż?!)

Rozróżniamy dwa środowiska działania, w których instaluje się i uruchamia aplikację JPA - środowisko Java EE i Java SE. Mimo, że oba muszą dostarczyć środowisko uruchomieniowe dla funkcjonowania JPA to ich sposób działania jest odmienny (ze względu na dostęp do usług pomocniczych, które są opcjonalne w Java SE podczas, gdy są obowiązkowe w Java EE, np. usługa monitora transakcyjnego).

Jak już pisano wcześniej (i wspomina się na każdym kroku w specyfikacji) każdy PU (jednostka utrwalania, ang. persistence unit) zawiera pojedyńczy plik persistence.xml - teraz dopiero zdałem sobie sprawę (a może jest późno i tak mi się tylko zdaje), że istnienie persistence.xml wyznacznikiem potencjalnych encji (dla sprawdzenia dotychczasowych umiejętności JPA proponuję mały test z pytaniem, czy możliwe jest dystrybuowanie archiwum z plikiem persistence.xml bez żadnych klas trwałych - odpowiedź na samym końcu wpisu). Brak persistence.xml to brak PU mimo, że mogłoby się zdarzyć, że istnieją w archiwum klasy udekorowane adnotacją @Entity. Poza persistence.xml PU zawiera pliki mapowania oraz klasy trwałe.

Podczas instalacji aplikacji kontener Java EE zobowiązany jest do przeszukania potencjalnych miejsc istnienia persistence.xml (było o tym w poprzedniej relacji). Każdy odszukany persistence.xml jest analizowany i wszelkie niezgodności formatu pliku ze schematem persistence_1_0.xsd muszą być natychmiast raportowane. Jeśli nie zdefiniowano dostawcy JPA i/lub źródła danych, informacja o nich musi być dostarczona podczas instalacji bądź ich wartości będą odpowiadały wartościom domyślnym kontenera. Kontener może dostarczyć dowolne właściwości specyficzne dla niego do dostawcy JPA podczas tworzenia fabryki zarządców trwałości dla danego PU.

Dla każdego PU odszukiwana jest implementacja javax.persistence.spi.PersistenceProvider. Implementacja PersistenceProvider będzie wołana do stworzenia fabryki zarządcy trwałości dla danego PU poprzez metodę createContainerEntityManagerFactory. Dane konfiguracyjne przekazywane są do metody poprzez egzemplarz klasy javax.persistence.spi.PersistenceUnitInfo. Wyłącznie pojedyńcza fabryka zarządcy trwałości będzie stworzona dla danego PU. Dowolna liczba zarządców trwałości może być utworzona przez pojedyńczą fabrykę.

Reinstalacja PU wymaga wywołania metody close na fabryce zarządców i wykonać createContainerEntityManagerFactory ponownie.

Dostawca JPA zobowiązany jest do przetworzenia informacji o trwałości z adnotacji klas trwałych.

Napotkanie pliku mapowania wymaga zweryfikowania jego poprawności względem orm_1_0.xsd.

Nie przewiduje się wywoływania implementacji javax.persistence.spi.PersistenceProvider z poziomu aplikacji.

W środowisku Java SE utworzenie fabryki zarządcy trwałości odbywa się poprzez metodę javax.persistence.Persistence#createEntityManagerFactory.

Dostawca JPA w środowisku Java SE powinien być dostawcą usługi w sensie Java, tj. w archiwum jar dostawcy w katalogu META-INF/services powinien znajdować się plik javax.persistence.spi.PersistenceProvider, który zawiera nazwę klasy implementującej interfejs javax.persistence.spi.PersistenceProvider. W ten sposób nastąpi automatyczna instalacja dostawcy w środowisku. Tak zainstalowany dostawca JPA będzie dostawcą domyślnym.

Następnie zaprezentowano przykład takiego rozwiązania, gdzie archiwum acme.jar będące archiwum JPA w katalogu META-INF/services zawiera plik javax.persistence.spi.PersistenceProvider, który z kolei zawiera nazwę klasy implementującej PersistenceProvider - com.acme.PersistenceProvider.

Na tym zakończył się rozdział 7.

Dla dociekliwych podaję odpowiedź na wyżej postawione pytanie, czy możliwe jest dystrybuowanie archiwum z plikiem persistence.xml bez żadnych klas trwałych. Odpowiedź jest TAK. W takiej sytuacji definiujemy PU dla aplikacji (modułu) na bazie klas trwałych, które dostępne są na...ścieżce klas (ang. classpath).