Archiwa tagów: Hibernate

Relacja wiele-do-wielu i Criteria API w JPA 2.0

Jakiś czas temu zapowiadałem pojawienie się artykułu na temat relacji wiele-do-wielu zrealizowanej za pomocą RequestFactory w GWT. Od tamtej pory trochę wody w Wiśle upłynęło, a ja z braku czasu nie miałem kiedy napisać o swoich poczynaniach. Jako że miniony weekend znalazłem trochę czasu i spędziłem go pod znakiem GWT, postanowiłem nadrobić zaległości.

Zdecydowałem się jednak rozdzielić temat RequestFactory od tematu JPA i opisać te dwa zagadnienia osobno. Podyktowane jest to przede wszystkim chęcią rozpisania się trochę o tym pierwszym, a i w związku z JPA chciałbym przedstawić kilka ciekawostek. Materiału trochę jest, więc zebranie tego wszystkiego razem tylko wydłużyłoby czas oczekiwania na nowy wpis. Sam projekt, a raczej kontynuacja tego rozpoczętego przy pierwszych bojach z RequestFactory i rozwijanego dalej podczas opisu możliwości walidacji encji w JPA i GWT, jest już prawie na ukończeniu i można go pobrać z repozytorium.

Relacja wiele-do-wielu (many-to-many) jest chyba najtrudniejszą relacją do zamodelowania i zrozumienia dla początkujących programistów. Jako jedyna po stronie bazy danych wymaga utworzenia osobnej tabeli (tzw. intersekcji) łączącej rekordy dwóch głównych tabel. Z tego też powodu zazwyczaj sprawia najwięcej trudności przy mapowaniu tabel na encje za pomocą JPA (podobnie zresztą w czystym Hibernate). Upraszczając problem, relację wiele-do-wielu można rozłożyć na dwie relacje jeden-do-wielu (one-to-many) i dołożyć mapowanie osobnej encji pełniącej rolę intersekcji. Wtedy jednak w encjach głównych dostaniemy bezpośredni dostęp za pomocą kolekcji jedynie do encji intersekcji, a nie do siebie nawzajem. Jak więc poprawnie napisać mapowanie wiele-do-wielu używając adnotacji @ManyToMany?
Czytaj więcej »

JPA i walidacja encji w projekcie GWT

Całkiem niedawno opisywałem moje boje z mechanizmem RequestFactory, który okazał się być całkiem fajnym tworem. Za jego pomocą udało się nam wtedy stworzyć aplikację z serwisami zorientowanymi na dane, gdzie warstwę dostępu do danych zapewniał nam Hibernate. Aplikacja potrafiła wykonać jedynie podstawowe operacje CRUD na pojedynczej encji i już wtedy zapowiedziałem, że w dalszym ciągu czekają na nas relacje między encjami oraz walidacja encji. Dzisiaj będę kontynuować stworzony wtedy projekt i zajmę się drugim z zapowiedzianych tematów, czyli normą JSR 303 definiującą reguły sprawdzania poprawności obiektów. Walidacja nie będzie skomplikowana i ma na celu jedynie pokazanie działania wraz z mechanizmem RequestFactory.

Aby materiału na dzisiaj nie było za mało, pokażę jak skonfigurować projekt, aby skorzystać ze standardu JPA, którego API zastąpi nam Hibernate’a. Ten ostatni będzie dalej obecny pod postacią dostawcy implementacji JPA, jednak jak zauważymy później, kod źródłowy będzie całkowicie od niego niezależny. Przy okazji pokuszę się o małe porównanie JPA z Hibernate’m.

Zacząłem trochę inaczej niż zawsze, gdyż na wstępie zazwyczaj skupiam się na sensowności/celu zastosowania danej technologii, a nie na tym co będziemy robić. Jeśli czujesz się trochę zawiedziony, to już to nadrabiam :) Po co używać więc JPA, jeśli mamy w projekcie doskonale działającego Hibernate’a? Po co uczyć się nowego, nieco innego API? Czy użycie JPA ma jakieś zalety, ewentualnie wady? Odpowiedzi na te pytania mogą być różne i wszystko zależy od tego, jaką aplikację tworzymy i w jakim środowisku będzie ona pracować. Przede wszystkim należy pamiętać, że Hibernate nie jest jedynym narzędziem ORM’owym i istnieje cała masa alternatywnych rozwiązań. Możemy np. trafić do zespołu, który będzie faworyzował Oraclowego TopLink‚a, bądź rozwijanego przez fundację Apache – Open JPA. Możemy też być uzależnieni od środowiska, np. osadzenie aplikacji na serwerze Google App Engine będzie wymagało od nas użycia DataNucleus‚a.

Czytaj więcej »

Alternatywa dla GWT-RPC: RequestFactory

Prawdopodobnie znasz już dobrze mechanizm GWT-RPC, który dostarcza podstawowy sposób komunikacji klient-serwer w projekcie wykorzystującym GWT. Mechanizm ten z powodzeniem działa już od pierwszych wersji GWT i mając z początku alternatywę jedynie w postaci ręcznych zapytań do serwletów http, wygrywa prawie każde starcie. Nie ustrzegł się jednak kilku dość istotnych wad (wynikających z ogólnej architektury aplikacji GWT), które nie tyle co coś uniemożliwiają, ale bardziej uprzykrzają życie programiście. O ile GWT-RPC w wywoływaniu prostych akcji sprawdza się świetnie, to implementacja dobrej warstwy pobierania danych jest już dość trudna. Problem leży w tym, że GWT nie potrafi zserializować obiektów encji wybieranych wprost z bazy danych poprzez np. Hibernate’a, które zawierają dowiązania do innych obiektów encji będących z nimi w relacji. W praktyce sprowadza się to do tego, że nie można stosować mapowań relacji typu „lazy”, gdyż informacje o relacjach przechowywane w obiektach encji nie mogą być zserializowane i przesłane do strony klienckiej. Relacje można więc sobie odpuścić (co jeszcze sprawdzi się w małej aplikacji), bądź przesyłać przez RPC obiekty specjalnych klas DTO (Data-Transfer Object), które będą zawierały jedynie niezbędne dla widoku informacje – a tu czeka nas ręczne i wolne przepakowywanie atrybutów obiektów oraz mozolne tworzenie klas DTO. Da się z tym żyć, jednak da się zrobić lepiej! Czytaj więcej »

Szyfrowanie danych w bazie danych za pomocą Jasypt + Hibernate

Jasypt Logo

Bezpieczeństwo danych przechowywanych w naszej aplikacji polega nie tylko na należytym zabezpieczeniu ekranu logowania oraz implementacji dobrego mechanizmu uwierzytelniania i autoryzacji użytkowników. Te dwa ostatnie zagadnienia można zrealizować chociażby przy pomocy certyfikatu SSL i usługi JAAS. Czasami wymaga się jednak, aby same dane były składowane w formie zaszyfrowanej. Najczęściej stosuje się tą metodę, jeśli dostęp do bazy danych może być uzyskany w jakikolwiek inny sposób, niż przez naszą aplikację. Odpowiednio zaimplementowany mechanizm zabezpiecza też dane w bazie przed nieautoryzowanym dostępem za pomocą potencjalnych luk w zaufanej aplikacji.

Szyfrowanie danych w bazie można zrealizować na wiele sposobów. Jednym z nich jest po prostu dopisanie do getterów i setterów naszych klas encji odpowiednich operacji szyfrowania i deszyfracji. Od stopnia zaawansowania poziomu zabezpieczenia zależy, jak duży bałagan w kodzie zrobimy i jak ciężko będzie to utrzymać. Z pomocą przychodzą biblioteki, które pozwalają na przeźroczyste szyfrowanie danych na poziomie np. Hibernate’a. Jedną z takich bibliotek jest Jasypt – narzędzie upraszczające operacje szyfrowania do niezbędnego minimum (przy czym oferujące równie zaawansowane możliwości, co API JCE – Java Cryptography Architecture). Jasypt doskonale sprawdza się w implementacjach własnych mechanizmów szyfrowania oraz integruje się z wieloma popularnymi technologiami jak Hibernate, Spring, Wicket czy JBoss Seam. Sam z siebie nie dostarcza żadnych algorytmów szyfrowania, jednak pozwala na dołączanie dodatkowych dostawców JCE umożliwiających korzystanie z bardziej zaawansowanych algorytmów jak AES czy WHIRLPOOL.

Czytaj więcej »

Obsługa transakcji JTA w projekcie GWT + Hibernate

Czasami bywa tak, że mamy gotowy już produkt, bądź większą jego część, ale w pewnym momencie musimy do niego dorobić coś, do czego nasz projekt od początku nie był przystosowany. Zazwyczaj pojawiają się wtedy dwa wyjścia. Pierwsze z nich zakłada głębsze zmiany w kodzie i architekturze aplikacji, aby dostosować ją do nowych potrzeb. Niestety jest to proces pracochłonny, czasochłonny, a ponadto będzie wymagał dogłębnego przetestowania aplikacji w zakresie praktycznie całej jej funkcjonalności. Jeśli nie możesz sobie na to pozwolić, zostaje jak zwykle drugie wyjście, czyli dorobienie czegoś „na szybko”, „na sztywno”, itp. Nie jest to ładne, ale jeśli klient czeka na gotowy produkt, czasem trzeba tak zrobić.

Dzisiejszy artykuł po części dotyka tematu wspomnianego „drugiego wyjścia”, gdyż to, co chcę Tobie zaprezentować, nie często występuje w przyrodzie w takiej właśnie postaci. Świadczy o tym chociażby ilość trafnych odpowiedzi w wyszukiwarce Google’a na zapytanie „GWT + JTA”. Oczywiście jeśli znasz temat, zaproponujesz Spring’a, bądź EJB. I słusznie! O wiele łatwiej jest skorzystać z mechanizmu transakcji JTA, gdy posiadamy wspomniane frameworki. Jeśli jednak masz już gotową, monolityczną aplikację napisaną w samym GWT, a musisz obsługiwać w niej transakcje poprzez JTA, być może zaoszczędzę Ci trochę czasu na rozpoznawanie tematu :) Oczywiście nic nie stoi na przeszkodzie, aby używać JTA w projekcie GWT już od samego początku, dzięki czemu uzyskamy kilka zalet płynących właśnie z wykorzystania tego mechanizmu transakcji.

Czytaj więcej »