05 lutego 2007

Java Persistence - Rozdział 3 Entity Operations - pierwsze rozdanie

Zanim przejdę do relacji z lektury JPA słówko o tłumaczeniu lifecycle. Ja wybrałem stadia rozwojowe/życiowe, ale nie mogę się do niego przyzwyczaić. Może są bardziej trafne tłumaczenia? Poszukuję czegoś bardziej technicznego, czegoś co być może już jest w użyciu, ale mnie omija.

Poza tym, w międzyczasie, kiedy szukałem informacji o SCBCD 5.0 (310-091) , o którym mówi się, że będzie pod koniec lutego, natrafiłem na 2 ciekawe strony z materiałami. Warto na nie zajrzeć!
Pora zatem na relację z pierwszego podrozdziału rozdziału 3. Rozdział 3 opisuje użycie EntityManager API do zarządzania stadiami instancji encji i użycie Query API do pozyskiwania i wyszukiwania ich trwałego stanu.

3.1 EntityManager (zarządca encji)

Instancja EntityManager związana jest z kontekstem utrwalania (ang. persistent context). Kontekst utrwalania (trwałości) jest zbiorem instancji encji, w którym dla dowolnego trwałego bytu istnieje unikatowa instancja encji. W ramach kontekstu utrwalania następuje zarządzanie stadiami instancji encji. EntityManager API dostarcza metod do interakcji z kontekstem utrwalania - tworzenie i usuwanie trwałych instancji encji, odszukiwanie encji według ich klucza głównego i do zapytań po encjach.

Zbiór encji, które są zarządzane przez daną instancję EntityManager, jest określona przez jednostkę utrwalania (ang. persistence unit). Jednostka utrwalania definiuje zbiór wszystkich klas mapowanych do wspólnej bazy danych.

Interfejs EntityManager należy do pakietu javax.persistence i dostarcza następujące metody:
  • void persist(Object entity) - utwórz trwałą instancję zarządzaną (innymi słowy: zapisz encję do bazy danych i kontroluj jej stan)
  • <T> T merge(T entity) - zsynchronizuj stan encji z aktualnym kontekstem utrwalania
  • void remove(Object entity) - usuń instancję encji
  • <T> T find(Class<T> entityClass, Object primaryKey)- znajdź encję po wartości jej klucza głównego
  • <T> T getReference(Class<T> entityClass, Object primaryKey) - pobierz instancję, której stan może być pobrany z opóźnieniem
  • void flush() - zapisz (utrwal) stan kontekstu utrwalania do bazy danych
  • void setFlushMode(FlushModeType flushMode) - ustaw tryb zapisu stanu kontekstu utrwalania dla wszystkich encji w nim zawartym
  • FlushModeType getFlushMode() - pobierz tryb zapisu stanu kontekstu trwałości dla wszystkich encji w nim zawartym
  • void lock(Object entity, LockModeType lockMode) - ustaw tryb blokady dla encji zawartej w kontekście trwałości
  • void refresh(Object entity) - odśwież stan instancji encji danymi z bazy danych, nadpisując wprowadzone zmiany w encji
  • void clear() - wyczyść kontekst utrwalania, powodując, że wszystkie encje staną się odłączone (ang. detached). Zmiany w encjach, które nie zostały zapisane w bazie (operacja flush) nie będą w niej utrwalone
  • boolean contains(Object entity) - sprawdź, czy instancja encji należy do aktualnego kontekstu utrwalania
  • Query createQuery(String qlString) - stwórz instancję typu Query do wykonania zapytania w języku zapytań JPA (JPA-QL)
  • Query createNamedQuery(String name) - stwórz instancję typu Query do wykonania nazwanego zapytania (w JPA-QL bądź SQL)
  • Query createNativeQuery(String sqlString) - stwórz instancję typu Query do wykonania zapytania SQL, tj. UPDATE lub DELETE
  • Query createNativeQuery(String sqlString, Class resultClass) - stwórz instancję typu Query do wykonania zapytania SQL, tj. UPDATE lub DELETE z tą różnicą, że typem instancji w wyniku będzie resultClass
  • Query createNativeQuery(String sqlString, String resultSetMapping) - stwórz instancję typu Query do wykonania zapytania SQL, tj. UPDATE lub DELETE, gdzie resultSetMapping wskazuje nazwę mapowania wyniku
  • void joinTransaction() - instruuje EntityManager, aby przyłączył się do aktywnej tranzakcji JTA
  • Object getDelegate() - zwróć implementację EM specyficzną dla dostawcy JPA
  • void close() - zamknij instancję EntityManager
  • boolean isOpen() - sprawdź, czy EntityManager jest otwarty (gotów do pracy)
  • EntityTransaction getTransaction() - zwróć zarządcę tranzakcji, w celu rozpoczynania i zatwierdzania pośrednich tranzakcji
Metody persist, merge, remove i refresh muszą być wywoływane w kontekście aktywnej tranzakcji, jeśli EntityManager działa w trybie tranzakcyjnego kontekstu utrwalania. Brak tranzakcji powoduje wyjątek javax.persistence.TransactionRequiredException.

Metody find oraz getReference nie wymagają aktywnej tranzakcji. Jeśli EntityManager działa w trybie tranzakcyjnego kontekstu utrwalania, zwrócone encje będą odłączone (nie będą zarządzane). EntityManager działający w trybie rozszerzonego kontekstu tranzakcyjnego, zwróci encje zarządzane. Więcej informacji niebawem, w sekcji 3.3.

Instancje Query oraz EntityTransaction są poprawne (aktywne), jeśli związane z otwartą instancją EntityManager'a (tj. metoda isOpen zwróci true).

W przypadku wystąpienia błędów z zapytaniem JPA-QL bądź SQL (niepoprawnie zbudowane, wykonanie, bądź rzutowanie wyników na zadany typ) rzucane są wyjątki IllegalArgumentException bądź javax.persistence.PersistenceException, który zakłada się, że zawiera wyjątek specyficzny dla bazy danych.

Wyjątki niekontrolowane (ang. unchecked exceptions - RuntimeException i pochodne) rzucane przez EntityManager powodują wycofanie aktywnej tranzakcji.

Metody close, isOpen, joinTransaction i getTransaction służą do zarządzania stadiami zarządcy encji kontrolowanymi przez aplikację (ang. application-managed entity manager). Więcej w nadchodzącym rozdziale.

Sekcja 3.1.2 zawiera przykładowe użycie EntityManager'a, poprzez wstrzelenie zależności za pomocą @PersistenceContext, a następnie użycie metody find do odszukania encji Customer o podanym kluczu głównym. Encja Customer jest w relacji z Order (zapewne jeden do wielu, ale to nie było zaprezentowane w przykładzie).

Następny podrozdział 3.2 będzie o stadiach życiowych encji (3.2 Entity Instance’s Life Cycle) i pobieżne przejrzenie materiału wskazuje, że nie będzie lekko.