piątek, 9 stycznia 2009

Kaskady pól Encji

Witam.
Każdy z nas pisząc encje z wykorzystaniem adnotacji, używał do określania relacji między nimi @OneToMany, @OneToOne i ustawiał kaskadę (jak w większości przykładów) cascade={CascadeType.ALL} (czyli przykładowo @OneToMany( cascade={CascadeType.ALL} ). Powoduje ona "przenoszenie" komend z obiektu, na którym wywołaliśmy polecenia EntityManger-a (persist, merge, remove) na zawartość pól kaskadowanych. Wszystko jest dobrze dopóki aplikacje i powiązania między encjami są proste. Jeżeli mamy na przykład sklepik z encjami Osoba i Bilet i ustawimy pełną kaskadowość. To przy usuwaniu osoby usuniemy też wszystkie bilety tej osoby. W tym wypadku wystarczy wyłączyć kaskadowość, ale w większych projektach może to być za mało.
Zobaczmy więc co za typy kaskadowania kryją się pod CascadeType.ALL.
Najważniejsze to:
  • CascadeType.PERSIST

  • CascadeType.MERGE

  • CascadeType.REMOVE

Pełna lista pod http://www.hibernate.org/hib_docs/annotations/reference/en/html_single/#entity-hibspec-cascade

Tak Więc jeśli chcemy by wraz z stworzeniem(w bazie) jakiegoś obiektu wiązało się z stworzeniem wszystkich jego pól "encyjnych" ustawiamy CascadeType.PERSIST gdy chcemy by update lub pobranie elementu powodowało update wszystkich pól, które są związane z encjami ustawiamy CascadeType.MERGE. Gdy chcemy ustawić kilka typów kaskadowania naraz wpisujemy je po przecinku. Przykładowo @OneToMany( cascade={CascadeType.MERGE, CascadeType.PERSIST})

W razie problemów z adnotacjami polecam wcześniej już podlinkowany poradnik do Hibernate-a http://www.hibernate.org/hib_docs/annotations/reference/en/html_single/. Będzie również pomocny przy korzystaniu z OpenJPA.
To tyle co miałem do powiedzenia jeżeli idzie o kaskadowanie.
Pytania (lub propozycje co do artykułów) pisać w komentarzach.
Pozdrawiam

3 komentarze:

  1. Taka uwaga mała jeszcze (nie wiem jak to opisać za bardzo, więc podam przykład :P)

    http://wklej.org/id/38145/

    Pierwsza metoda, która deklaratywnie zwraca ArrayList zostanie przetrawiona przez Geronimo, ale Hajbernejt JBossowy wyrzuci persistence context error czy coś w ten deseń. Wszystko co trzeba do wiadomości przyjąć w takim wypadku, to deklaratywne napisanie, że metoda zwraca List(nawet jeśli zwraca rzeczywiście ArrayList) - to już hajbernejt przetrawi ;) Oczywiście głowy sobie za to uciąć nie dam, ale taki właśnie ja miałem problem ;D Pozdro :)

    OdpowiedzUsuń
  2. Nie wiem jak to jest z niedziałaniem ArrayListy, ale podczas przeglądania przykładowych beanów czy encji zawsze spotykałem się raczej z Listami.
    Z poradnika do hibernate-a wynika też, że jeśli chcemy zwrócic HashMape to musimy zwrócic Map.
    Widac twórcy uznali, że lepiej przesyłac typ bardziej prymitywny.
    Dzięki za uwagę może się komuś przydac.

    OdpowiedzUsuń
  3. Przecież to są podstawowe zasady higieny polimorficzno-obiektowej, zwracać typ interfejsu, przyjmować jako parametry metod typy interfejsów a nie realizacji. No chyba że ktoś przesadził, i zrobił typ zwraca lny na przykład java.lang.Iterable, w którym za mało metod. Ale to juz problem projektanta frameworku.

    OdpowiedzUsuń