04 maja 2007

Java Persistence - Rozdział 5.1 Konteksty trwałe

Trochę minęło od ostatniej relacji specyfikacji Java Persistence API i czym bliżej końca tym coraz ciężej. Czasami zastanawiam się, czy dany temat nie był już omawiany i czy warto jest do niego wracać, albo czy nie powinienem zaprezentować krótkiego przykładu wspomagającego. Cały czas marzy mi się podejście do egzaminu z SCBCD 5, a tam mimo wielu pytań z JPA są również z EJB 3.0. Nie mogę się już doczekać, kiedy uda mi się zestawić środowisko z GF (GlassFish), JBAS (JBoss AS) oraz AG (Apache Geronimo), z którym będę mógł dalej rozpracowywać specyfikację EJB 3.0 i w końcu dotknąć JPA w środowisku tranzakcyjnym zarządzanym przez serwer aplikacyjny. Pora więc zamknąć temat JPA. Powracam do specyfikacji od lektury podrozdziału 5.1 Konteksty trwałe.

Okazuje się, że i w specyfikacji ten sam byt ma wiele równouprawnych nazw - zarządca trwałości (ang. persistence manager) oraz zarządca encji (ang. entity manager). Oba dotyczą tego samego pojęcia w specyfikacji Java Persistence i określają klasę, która realizuje wymagania specyfikacji JPA w zakresie zarządzania cyklem życia encji. Ja również używam pojęcia dostawca trwałości/JPA dla określenia zarządcy, chociaż to pojawia się zazwyczaj w kontekście (uwaga na kontekst użycia słowa kontekst ;-)) omawiania produktu/projektu dostarczającego realizację specyfikacji JPA, niż samego jego użycia w środowisku uruchomieniowym. Coraz częściej zaczynam używać przymiotnika trwały zamiast formy rzeczownika trwałości do określenia pojęć JPA, np. kontekst trwały zamiast kontekst trwałości. Różnie bywa i czasami samemu łapię się na zamiennym ich używaniu.

5.1 Konteksty trwałe

Kontekst trwały jest zbiorem egzemplarzy encji, w którym dla dowolnego identyfikatora encji istnieje unikatowy egzemplarz encji. W ramach kontekstu, zarządca encji (trwałości/trwały) kontroluje egzemplarze encji oraz ich cykle rozwojowe. Innymi słowy, mając pojedyńczego zarządcę trwałości możemy wyróżnić wiele kontekstów trwałości, każdy z pewnymi identyfikatorami encji, które wskazują na poszczególne egzemplarze encji w odpowiednim stadium życiowym i stanie (dla dalszego skomplikowania^H^H^Huproszczenia sytuacji, nie można również zapomnieć o jednostce trwałości, która tak na prawdę grupuje klasy encji i dopiero ona jest "źródłem" kontekstów dla wybranego dostawcy trwałości).

W środowisku Java EE, tranzakcja JTA zazwyczaj angażuje wiele komponentów, tj. składa się z wielu wywołań zasobów pod auspicjami aktywnej tranzakcji. Komponenty często mogą potrzebować dostępu do tego samego kontekstu trwałości w ramach pojedyńczej tranzakcji. Aby umożliwić takie wykorzystanie zarządców trwałości w środowisku Java EE, kiedy zarządca trwałości jest przekazywany (wstrzeliwany) do komponentu bądź wyszukany w drzewie JNDI, jego kontekst trwałości jest automatycznie związywany z aktualną tranzakcją, a wszystkie referencje do EntityManager, które wskazują na tą samą jednostkę trwałości będą udostępniały ten sam kontekst trwałości w ramach danej tranzakcji. Przekazywanie kontekstu trwałości przez kontener (serwer aplikacyjny) Java EE zapobiega konieczności przekazywania referencji egzemplarzy EntityManager z jednej części aplikacji do drugiej. Zarządca trwałości, dla którego kontener (serwer aplikacyjny) zarządza kontekstem trwałości w ten sposób, nazywany jest zarządcą trwałości zarządzanym przez kontener (ang. container-managed entity manager). Cyklem życia zarządcy trwałości zarządzanym przez kontener zarządza kontener Java EE (mimo, że użycie kontener Java EE może pomagać w zrozumieniu pojęcia "zarządca trwałości zarządzany przez kontener", ja będę częściej używał serwer aplikacyjny w tym znaczeniu chyba, że będzie to powodowalo niejasności).

W bardzo rzadkich przypadkach w środowisku Java EE, aplikacje mogą korzystać z kontekstów trwałości, które są samodzielne (w sensie braku zarządzania nimi przez serwer aplikacyjny), tj. nie przekazywanych z aktualną tranzakcją JTA w ramach referencji EntityManager dla danej jednostki utrwalania. W takich przypadkach, każde wystąpienie referencji EntityManager powoduje utworzenie nowego samodzielnego (odłączonego) kontekstu trwałego, który nie jest dostępny dla innych referencji EntityManager tej samej jednostki trwałej w ramach tej samej tranzakcji. Takie użycie możliwe jest dzięki metodzie javax.persistence.EntityManagerFactory.createEntityManager. Zarządcę trwałości, którego konteksty trwałe są tworzone i niszczone w ten sposób nazywa sie zarządcą trwałości zarządzanym przez aplikację (ang. application-managed entity manager). Cyklem życia zarządcy trwałości zarządzanym przez aplikację zarządza aplikacja (metody EntityManagerFactory.createEntityManager oraz EntityManager.close lub całkowite zamknięcie fabryki zarządców za pomocą EntityManagerFactory.close).

Wsparcie dla obu typów zarządców - zarządzanych przez kontener lub aplikację - jest wymagane przez kontenery aplikacji internetowych i EJB w serwerze aplikacyjnym Java EE. W ramach kontenera EJB najczęściej korzysta się z zarządców trwałości zarządzanych przez kontener.

W środowisku Java SE oraz kontenerze klientów aplikacyjnych Java EE wymagane jest jedynie wsparcie dla zarządców trwałości zarządzanych przez aplikację (pojawia się notka - żeby nie napisać adnotacja - w specyfikacji o opcjonalnym wsparciu dla JTA w kontenerze klientów aplikacyjnych Java EE).

Dla zobrazowania tematu wydaje się koniecznym, aby kolejna odsłona relacji ze specyfikacji JPA musiała zacząć się od przykładu z jednostką trwałą w trybie JTA i RESOURCE_LOCAL z serwerem GlassFish (TopLink JPA), JBoss AS (Hibernate JPA) i Apache Geronimo (OpenJPA). Będzie to dobrą rozgrzewką do zestawienia środowiska do testowania specyfikacji EJB 3.0 z różnymi serwerami aplikacyjnymi Java EE 5. Kolejna relacja zapowiada się bardzo ciekawie.