Analiza porównawcza technologii implementacji warstwy

Transkrypt

Analiza porównawcza technologii implementacji warstwy
XVI Konferencja PLOUG
Kościelisko
Październik 2010
Analiza porównawcza technologii
implementacji warstwy dostępu
do danych w aplikacjach ADF
Paweł Boiński
Politechnika Poznańska
[email protected]
Abstrakt. Twórcy wielowarstwowych aplikacji ADF najczęściej implementują warstwy dostępu do bazy danych korzystając z jednej
z dwóch kluczowych technologii: ADF Business Components lub Enterprise Java Beans. Celem tego referatu jest porównawcza analiza
obu rozwiązań, uwzględniająca aspekty funkcjonalne, narzędziowe i efektywnościowe. Autor przedstawi m.in. wyniki złożonego
eksperymentu wydajnościowego, w ramach którego badano efektywność realizacji operacji dostępu do danych.
Informacja o autorze. Paweł Boiński pracuje w Instytucie Informatyki Politechniki Poznańskiej. Specjalizuje się w systemach baz
danych, przestrzennych bazach danych i eksploracji danych.
Analiza porównawcza technologii implementacji warstwy dostępu do danych...
295
1. Wprowadzenie
Java EE [JEE] jest platformą, która bardzo często stanowi podstawę oprogramowania korporacyjnego. W praktyce, Java EE, stanowi zaledwie zbiór zasad i specyfikacji określających strukturę
oprogramowania budowanego w oparciu o architekturę wielowarstwową. Ze względu na bardzo
rozbudowany zakres opisywanych zagadnień, platforma Java EE może stanowić dla wielu programistów i projektantów zbyt skomplikowane środowisko. Przez wiele lat opracowywano wzorce
projektowe oraz tzw. najlepsze praktyki w pracy z Java EE. Ich wykorzystanie wiąże się jednak
często z koniecznością pisania dużej ilości kodu, który nie jest przeznaczony do wykonywania
konkretnych funkcji biznesowych, lecz służy do implementacji struktury aplikacji. Wymusiło to
na deweloperach poszukiwanie nowych rozwiązań. Wraz z debiutem środowiska Oracle JDeveloper 10g Release 2 wprowadzona została koncepcja Oracle Application Development Framework
(w skrócie: Oracle ADF) [ADF]. Oracle ADF jest frameworkiem wykorzystującym platformę Java
EE i zawiera implementację najbardziej popularnych wzorców projektowych. Dodatkowo wprowadzone zostały edytory wizualne, dzięki którym możliwe jest szybkie tworzenie najczęściej
spotykanych elementów aplikacji. Zgodnie ze schematem wyznaczonym przez Java EE, Framework Oracle ADF definiuje wielowarstwową architekturę aplikacji. Jedną z kluczowych cech
Oracle ADF jest pozostawienie programiście dużej swobody wyboru konkretnych technologii
implementacji każdej z warstw aplikacji. Wybór technologii, choć uelastycznia pracę projektanta
aplikacji, wymaga od takiej osoby znacznie większego zakresu wiedzy na temat dostępnych rozwiązań. Zły wybór na etapie projektowania aplikacji może mieć poważne konsekwencje w dalszych krokach procesu wytwarzania oprogramowania. O ile na etapie implementacji zmiana technologii może być stosunkowo prosta, o tyle zdiagnozowanie złego wyboru na etapie testowania
lub (co gorsza) na etapie użytkowania, może skutkować bardzo wysokimi kosztami naprawy tej
sytuacji. Jeden z czarnych scenariuszy polegać może na złej ocenie wydajności konkretnej technologii w odniesieniu do skalowalności. Problem ten często pojawia się zwłaszcza w aplikacjach
internetowych, gdzie ilość danych i użytkowników może wzrosnąć w stopniu dramatycznym
w bardzo krótkim czasie.
W ramach niniejszego tekstu podjęta została próba odpowiedzi na pytanie, jaką strategię wybrać w implementacji warstwy dostępu do danych w aplikacjach ADF w sytuacji, gdy spodziewana jest znacząca ilość danych przetwarzanych przez aplikację. Rozważania dotyczą przede
wszystkim aspektu wydajnościowego przyjętego rozwiązania, ale poruszone zostały także kwestie
funkcjonalności i dostępności specjalizowanych narzędzi. Analizie poddano dwie popularne technologie dostępu do danych: Enterprise Java Beans 3.0 (w skrócie: EJB 3.0) [EJB30] oraz ADF
Business Components. Struktura tekstu jest następująca. W rozdziale drugim przedstawiona została architektura typowej aplikacji ADF wraz z umiejscowieniem w niej warstwy dostępu do danych. Opisano również, w zwięzłej formie, technologie implementacji, które zostały poddane analizie: ADF Business Components oraz Hibernate i EclipseLink. W rozdziale trzecim zostało opisane środowisko testowe oraz rodzaje przeprowadzonych testów wraz z ich wynikami i interpretacją.
2. Warstwa dostępu do danych w architekturze Oracle ADF
Architektura Oracle ADF oparta jest o popularny wzorzec Model-View-Controller (w skrócie:
MVC), który ułatwia utrzymywanie i ponowne wykorzystywanie implementowanych komponentów aplikacji. Oracle ADF rozszerza trzy warstwy MVC i składa się z następujących warstw podstawowych:
• widok – zawiera implementację interfejsu użytkownika,
296
Paweł Boiński
• kontroler – kieruje przepływem sterowania aplikacji (np. pomiędzy stronami aplikacji inter-
netowej),
• usługi biznesowe – udostępnia dane z różnych źródeł,
• model – pośredniczy między warstwą usług biznesowych a kontrolerem i widokiem.
Wymienione warstwy są ze sobą luźno powiązane, co skutkuje dużą elastycznością w doborze
konkretnej techniki implementacji każdej z nich. Na przykład, warstwa widoku może wykorzystywać interfejs WWW lub opierać się na aplikacji desktopowej korzystającej z komponentów
ADF Swing do prezentacji danych pochodzących z różnych źródeł danych.
Na szczególną uwagę zasługuje warstwa modelu, która stanowi element pośredniczący w komunikacji kontrolera i komponentów z warstwy widoku z obiektami odpowiedzialnymi za interakcję z bazą danych (lub innym źródłem danych). Warstwa modelu zaproponowana przez firmę
Oracle, stała się podstawą dla specyfikacji JSR-227 „A Standard Data Binding & Data Access
Facility for J2EE” [JSR227]. W dużym uproszczeniu można powiedzieć, że warstwa modelu
w Oracle ADF, udostępnia pojedynczy interfejs dla komunikacji z dowolną implementacją usług
biznesowych.
Warstwa usług biznesowych dostarcza funkcjonalności w zakresie operacji takich jak utrwalanie danych, zarządzanie transakcjami, mapowanie obiektowo-relacyjne oraz wykonywanie przetwarzania logiki biznesowej. Wśród technologii implementacji tej warstwy można wyróżnić m.in.:
• proste klasy Java,
• usługi typu web services,
• EJB,
• Oracle ADF Business Components.
W przypadku EJB, w 2006 roku, została sformułowana specyfikacja definiująca wersję oznaczoną numerem 3.0 tej technologii. W skład specyfikacji wszedł również dokument [JSR220]
opisujący zarządzanie trwałością danych oraz odwzorowanie obiektowo-relacyjne w aplikacjach
Java EE (a także Java SE w wersji 5 i 6). Technologia ta znana jest pod nazwą Java Persistence
API (w skrócie: JPA) i w znaczący sposób upraszcza model przetwarzania, znany z poprzedniej
wersji EJB.
Przedstawiona różnorodność metod dostępu do danych sprawia, że na etapie projektowania
aplikacji konieczne staje się rozważenie wielu czynników wpływających na wybór konkretnej
technologii. Wśród najważniejszych aspektów można wyróżnić następujące elementy:
• znajomość technologii przez zespół programistów,
• dostępność dokumentacji,
• dojrzałość,
• wsparcie producenta,
• zakres oferowanych mechanizmów,
• wydajność,
• skalowalność,
• cenę.
W dalszej części artykułu zostanie omówiony problem wyboru technologii implementacji warstwy usług biznesowych, a konkretnie metod dostępu do danych znajdujących się w bazie danych.
Jako nadrzędne kryterium decydujące o wyborze przyjęto wydajność operacji odczytu, zapisu
i modyfikacji danych.
Analiza porównawcza technologii implementacji warstwy dostępu do danych...
297
2.1. Technologie implementacji warstwy dostępu do danych
Twórcy architektury Oracle ADF, dając do wyboru projektantowi sposób dostępu do trwałych
danych, nie wskazali „jedynego słusznego” rozwiązania, chociaż podano tzw. zalecane zestawy
technologii w zależności od umiejętności programistów:
• ADF Business Components, JSF, JSF Faces – dla osób migrujących z technologii Oracle
Forms [Ora06][Ora10a]
• EJB 3.0/JPA, JSF, JSF Faces – dla osób, które mają doświadczenie z programowaniem Java
EE oraz dla wszystkich nowych aplikacji [Ora10b].
Firma Oracle udostępnia dla programistów szereg książek dokumentujących zarówno wykorzystanie ADF Business Components, jak również EJB 3.0/JPA. Należy zwrócić jednak uwagę, że
zdecydowana większość publikowanych materiałów o ADF opisuje aplikacje wykorzystujące
ADF Business Components.
Przeprowadzone badania wydajności obejmowały porównanie ADF Business Components
z dwoma implementacjami EJB 3.0/JPA: Hibernate [HIB] oraz EclipseLink [EL]. W kolejnych
podpunktach zostały krótko przedstawione powyższe technologie dostępu do danych.
2.1.1. ADF Business Components
Komponenty biznesowe wywodzą się z technologii Business Components for Java (w skrócie:
BC4J) i od wielu lat stanowią jedną z kluczowych technologii firmy Oracle. Wśród oferowanych
funkcjonalności można wyróżnić m.in.:
• automatyczne zarządzanie odwzorowaniem obiektowo-relacyjnym,
• możliwość definiowania złożonych poleceń SQL,
• możliwość implementacji złożonego przetwarzania biznesowego,
• obsługę transakcji,
• możliwość definiowania deklaratywnych reguł poprawności,
• dostęp do procedur składowanych,
• obsługę list wartości (ang. list of values).
W ADF Business Components można wykorzystać także deklaratywne walidatory poprawności danych: compareValidator, listValidator, rangeValidator oraz methodValidator. Sprawdzają
one, odpowiednio, czy wartość jest równa podanemu literałowi, czy należy do statycznej lub dynamicznej listy wartości, czy znajduje się w zakresie wartości. W przypadku najbardziej zaawansowanego walidatora, czyli walidatora typu methodValidator, użytkownik definiuje metodę, która
zwraca wartość prawda lub fałsz określającą, czy wartość została zatwierdzona lub odrzucona.
W skład ADF Business Components wchodzą następujące komponenty:
• obiekty encyjne – służą do reprezentacji danych (np. wierszy z relacji) i odpowiadają za
trwałość i walidację danych,
• asocjacje – definiują zależności relacyjne pomiędzy obiektami,
• obiekty perspektyw – organizują dane z obiektów encyjnych udostępniając je innym kom-
ponentom aplikacji, posiadają również możliwość filtrowania danych oraz formatowania ich
reprezentacji,
• moduły aplikacji – udostępniają obiekty perspektyw dla innych elementów aplikacji i od-
powiadają za zarządzanie transakcjami.
298
Paweł Boiński
Typowe działanie przy tworzeniu aplikacji ADF z wykorzystaniem komponentów biznesowych
polega na utworzeniu obiektów encyjnych oraz asocjacji dla tych obiektów. Następnie, tworzone
są obiekty perspektyw które mogą korzystać z przygotowanych obiektów encyjnych. Całość dopełniają moduły aplikacji, które stanowią interfejs dla klientów. Automatycznie tworzone są kontrolki danych implementujące JSR-227, które zapewniają współpracę z takimi komponentami jak
elementy interfejsu użytkownika.
Za wadę ADF Business Components można uznać rozbudowaną strukturę opisu obiektów tworzących komponenty. Klasy takich obiektów nie są klasami POJO (skrót od Plain Old Java Object)
– dziedziczą po określonych klasach dostarczonych przez framework. Wpływa to również na poziom złożoności kodu. Na przykład, obiekt encji może być opisany przez cztery pliki:
• pliku XML z opisem m.in.: mapowania obiektowo-relacyjnego, walidatorów poprawności
danych,
• pliku z definicją klasy, na której podstawie tworzone są instancje obiektu encyjnego,
• pliku z definicją obiektu encyjnego, która może być użyta do niestandardowego przetwarza-
nia deskryptorów z pliku XML,
• pliku z klasą opisującą kolekcję encji służącą do reprezentacji obiektów w pamięci podręcz-
nej dla pojedynczego użytkownika.
2.1.2. EJB3.0/JPA
Idea JPA polega na jak największym uproszczeniu kodu potrzebnego do obsługi operacji komunikacji z relacyjną bazą danych wraz z jednoczesnym zachowaniem obiektowego charakteru
aplikacji. JPA jest oparte na odwzorowaniu obiektowo-relacyjnym, które zakłada, że krotki przechowywane w relacjach bazodanowych są reprezentowane w postaci obiektów środowiska Java.
Takie obiekty nazywane są encjami JPA i stanowią instancje zwyczajnych klas Java typu POJO.
Określanie, które obiekty mają być przechowywane w bazie danych oraz zasady obowiązujące
przy ich zapisie lub odczycie, specyfikowane są za pomocą plików XML lub za pomocą tzw. adnotacji języka Java. Druga z metod jest bardziej popularna, a jej główną zaletą jest prostota i zwięzłość zapisu (w stosunku do rozbudowanych plików XML). Związki pomiędzy relacjami w bazie
danych reprezentowane są także w postaci adnotacji lub opisów XML.
JPA wprowadza koncepcję tzw. zarządcy encji (EntityManager) będącego obiektem odpowiedzialnym za cykl życia każdej z przetwarzanych encji. Instancje klas encji, które nie zostały
utrwalone przez zarządcę encji, zachowują się jak zwyczajne obiekty języka Java. Zdefiniowane
zostały również takie elementy jak API dla zatwierdzania i wycofywania transakcji, czy też zarządzanie wersjami obiektów i blokowaniem krotek. Operacje odczytu obiektów odbywać się mogą
przy wykorzystaniu API dla zapytań, które obejmuje zarówno zapytania nazwane (statyczne,
podane np. w postaci adnotacji), jak również zapytania dynamicznie konstruowane w czasie wykonania programu. Zdefiniowany został nowy język zapytań Java Persistence Query Language
(w skrócie JPQL), który jest rozbudowaną wersją Enterprise JavaBeans Query Language [EJB30].
Istnieje również możliwość wykonania natywnego polecenia języka SQL.
W typowych aplikacjach Java EE, na początku tworzone są obiekty encji reprezentujące relacje
w bazie danych, a następnie fasada sesji (ang. session facade), która staje się interfejsem dla
klienta. W aplikacjach ADF wykorzystujących JPA, oprócz utworzenia obiektów encyjnych oraz
fasady sesji, najczęściej konstruowane są kontrolki danych, które udostępniają dane i logikę z fasady sesji. Taka kontrolka danych może być następnie efektywnie wykorzystana przez komponenty interfejsu użytkownika.
Pierwsza specyfikacja JPA nie zawierała uwag dotyczących pamięci podręcznej (cache) dla
obiektów. W tym przypadku na większą precyzję zdecydowano się dopiero w wersji 2.0. Pomimo
braku wymagań odnośnie pamięci podręcznej, wszyscy liczący się dostawcy implementacji JPA
Analiza porównawcza technologii implementacji warstwy dostępu do danych...
299
w wersji 1.0 oferują jednak taki mechanizm w swoich produktach. Niniejszy artykuł dotyczy JPA
1.0. Analizie poddane zostały dwie, prawdopodobnie najpopularniejsze, implementacje JPA: Hibernate i EclipseLink.
Hibernate
Projekt Hibernate został zapoczątkowany w 2001 roku. Miał stać się alternatywą dla promowanej ówcześnie platformy EJB w wersji drugiej. Celem Hibernate było uproszczenie metod dostępu
do danych oferowanych przez EJB2 przy jednoczesnej rozbudowie dostarczanych funkcjonalności. Hibernate został następnie przejęty przez firmę JBoss, Inc., która od tego czasu kieruje dalszym rozwojem projektu. Sama firma JBoss, Inc. została natomiast włączona w skład grupy Red
Hat w roku 2006. W obecnej chwili dostępna jest trzecia wersja biblioteki Hibernate, która jest
certyfikowaną implementacją standardu JPA 1.0 oraz JPA 2.0. Hibernate udostępniany jest na
licencji GNU Lesser General Public License. Oznacza to, że jest darmowy zarówno dla użytku
deweloperskiego, jak również w środowiskach produkcyjnych.
Wychodząc poza standardowe funkcjonalności, biblioteka Hibernate oferuje m.in. własny język
zapytań HQL oraz definiowane kryteria dla zapytań (ang. criteria queries). Ciekawym aspektem
jest również obecność projektu NHibernate, który jest implementacją funkcjonalności Hibernate
przeniesioną na platformę Microsoft .NET. Pozwala to bardzo efektywnie wykorzystać nabytą
wiedzę przy pracy z różnymi projektami.
Biblioteka Hibernate jest wspierana przez wiele narzędzi, m.in. przez środowiska programistyczne Netbeans oraz Eclipse. W przypadku środowiska Eclipse, jest to zbiór wtyczek wchodzących w skład projektu HibernateTools [HT]. Oferuje on takie funkcjonalności jak edytor plików
XML wraz z semantycznym autouzupełnianiem, kreatory dla tworzenia konfiguracji oraz tzw.
reverse engineering używany do generowania definicji na podstawie istniejącego już schematu
bazy danych.
EclipseLink
EclipseLink wywodzi się z projektu Oracle TopLink. Firma Oracle w 2008 roku powierzyła
fundacji Eclipse zarządzanie otwartym projektem opracowanym na podstawie własnego produktu.
W EclipseLink znalazła się pełna funkcjonalność znana z Oracle Toplink. Szczególną uwagę powierzono zgodności ze standardami, w tym zgodności ze standardem JPA. Podobnie jak w przypadku biblioteki Hibernate, obecna implementacja EclipseLink jest zgodna zarówno ze specyfikacjami JPA 1.0 oraz JPA 2.0.
W stosunku do biblioteki Hibernate, implementacja EclipseLink oferuje lepsze wsparcie dla
mechanizmów bazy danych Oracle. Obejmuje to takie aspekty jak:
• możliwość łatwego wykorzystywania wskazówek zapytań, specyficznych dla bazy Oracle,
• łatwiejszy dostęp do wywoływania procedur składowanych,
• obsługę obiektów przestrzennych,
• obsługę wirtualnych, prywatnych baz danych.
W zakresie wsparcia w postaci narzędzi programistycznych, podobnie jak w przypadku Hibernate, wiele środowisk ma wbudowaną obsługę EclipseLink (np. JDeveloper) lub istnieją odpowiednie wtyczki dodające taką funkcjonalność. Na architekturze środowiska Eclipse zbudowany
jest projekt Web Tools Platform [WTP], którego jeden z elementów stanowi Eclipse Dali – projekt
wspierający operacje związane z tworzeniem mapowania obiektowo-relacyjnego przy użyciu JPA
i EclipseLink. Biblioteka EclipseLink jest udostępniana na licencji Eclipse Public License.
300
Paweł Boiński
3. Testy wydajnościowe
Jednym z istotnych kryteriów przy doborze technologii może być wydajność wybranego rozwiązania. W celu określenia, która z przedstawionych technologii implementacji warstwy dostępu
do danych w aplikacjach ADF charakteryzuje się większą efektywnością, przeprowadzono szereg
testów wydajnościowych. Ze względu na ograniczoną, maksymalną długość artykułu, przedstawione zostały wybrane wyniki badań.
3.1. Środowisko testowe
Do wykonania testów wykorzystano dwie stacje robocze. Parametry obu stacji zostały podane
w tab. 1. Na pierwszej stacji zainstalowano bazę danych Oracle 11gR2, natomiast na drugiej uruchomiona była aplikacja ADF. Dzięki takiemu rozwiązaniu zredukowana została możliwość wystąpienia nieprawidłowych odczytów czasów wykonania spowodowana przez aplikacje rywalizujące o zasoby. Stacje robocze zostały połączone łączem o przepustowości 100mbp/s. Przeprowadzone testy obejmowały porównanie technologii ADF Business Components z JPA. W przypadku
technologii JPA użyta została implementacja EclipseLink (wersja 2.0.2) oraz Hibernate (wersja
3.2.3). Serwer WebLogic podczas testów działał w trybie produkcyjnym z ograniczonym, do niezbędnego minimum, logowaniem ewentualnych błędów.
Tabela 1. Parametry środowiska testowego
Stacja robocza 1
Konfiguracja sprzętowa
Baza danych
Serwer aplikacji
Implementacja JPA
AMD Phenom X3 2800MHz,
4GB RAM, HDD 500GB
7200RPM
Oracle 11g Release 11.2.0.1.0
Stacja robocza 2
Intel Core2Duo 1800MHz,
2GB RAM, HDD 200GB
5400 RPM
WebLogic Server 10.3.3.0
EclipseLink 2.0.2
Hibernate 3.2.3
Schemat bazy danych obejmował trzy relacje połączone związkami typu jeden do wiele. W bazie danych znajdowało się 11 mln krotek. Dołożono wszelkich starań, aby testy wykonywane były
w tych samych warunkach. Uzyskane wyniki oparte są o średnią otrzymaną z wykonania dziesięciu iteracji każdego z testów. Podczas wszystkich testów parametr fetch size sterownika JDBC
(ang. Java Database Connectivity) był ustawiony na wartość 50. Eksperymenty przeprowadzano
dla wstawienia/odczytu/modyfikacji/usunięcia od 10000 do 50000 krotek z krokiem co 10000.
Przeprowadzone testy obejmowały eksperymenty na obiektach encyjnych oraz obiektach perspektyw dla technologii ADF Business Components (w opisach i na wykresach użyty został skrót
od nazwy: ADF BC). W przypadku technologii JPA, testy były wykonane przy użyciu implementacji Hibernate i EclipseLink. Wykorzystane zostały obiekty encji JPA oraz zapytania języka
JPQL.
3.2. Opis testów i wyników
W kolejnych podpunktach zostały przedstawione opisy przeprowadzonych testów oraz uzyskanych wyników eksperymentów.
Analiza porównawcza technologii implementacji warstwy dostępu do danych...
301
3.2.1. Losowy odczyt obiektów
Odczyt losowy obiektów, fetch size = 50
90,00
EclipseLink - encje JPA
80,00
Czas wykonania [s]
70,00
60,00
Hibernate - encje JPA
Hibernate - JPQL + optymalizacja
ADF BC - obiekt encji
ADF BC - obiekt perspektywy + optymalizacja
ADF BC - obiekt perspektywy
50,00
40,00
30,00
20,00
10,00
0,00
10000
20000
30000
40000
50000
Liczba obiektów
Rys. 1. Losowy odczyt obiektów
Pierwszy z przeprowadzonych testów obejmował operację odczytu losowo wybranych obiektów z bazy danych. Selekcja była oparta o identyfikator krotki/obiektu. Ze względu na rozmiar
danych w bazie danych, przekraczający znacznie liczbę odczytywanych krotek, liczba trafień
w pamięć podręczną była znikoma.
W ramach testów wykorzystano encje JPA oraz obiekty encji ADF Business Components (standardowe parametry). Do wykonania przetwarzania użyto także:
• dla JPA – zapytań JPQL – przeprowadzone badania wykorzystywały polecenia JPQL za-
równo bez wskazówek (ang. hints), jak również ze wskazówkami dotyczącymi wykonania
zapytań. Użyta wskazówka definiowała przechowywanie w pamięci przygotowanych zapytań (dla Hibernate jest to ustawienie parametru cacheable na wartość true).
• dla ADF BC – obiektów perspektyw – w wersji podstawowej obiekt perspektywy zdefinio-
wany był na obiektach encyjnych z wyszukiwaniem po identyfikatorze przy wykorzystaniu
metody findByPK. Wersja zoptymalizowana (oznaczona na wykresie słowem optymalizacja) zakładała wykorzystanie klauzuli WHERE polecenia SQL zdefiniowanego w obiekcie
perspektywy. Wprowadzono do tej klauzuli warunek równościowy na identyfikatorze krotki. Ponieważ każde zapytanie polega na odczycie jednej krotki z bazy danych, metoda odczytu danych z bazy danych przez obiekt perspektywy Retrieve from database, została
ustawiona na At most one row.
Uzyskane wyniki (patrz rys. 1) wskazują na największa efektywność przy wykorzystaniu
obiektów encji (technologia ADF Business Components). Jednocześnie najgorsze wyniki również
dotyczę ADF Business Components, jednak przy użyciu obiektów perspektyw. Dla technologii
JPA najlepsze wyniki osiągnięto w przypadku użycia encji JPA w implementacji Hibernate, które
znacznie wyprzedziły implementację EclipseLink. Na wykresie nie zamieszczono wyników uzyskanych przy wykorzystaniu języka JPQL bez użycia wskazówek. W obu przypadkach (Hiberanate, EclipseLink) uzyskane wyniki tak bardzo odbiegały od pozostałych rezultatów, że wymagałyby użycia innej skali. Na przykład dla technologii Hibernate przy odczycie 20000 obiektów czas
wynosił ok. 1500 sekund. Implementacja EclipseLink wykazała się lepszymi wynikami, jednak
i tak kilkadziesiąt razy gorszymi niż w przypadku użycia encji JPA. Próba optymalizacji zapytań
JPQL dała pozytywne wyniki w ramach poleceń Hibernate. Uzyskany wynik (na wykresie oznaczony jako JPQL + optymalizacja) jest wolniejszy od encji JPA Hibernate, ale szybszy niż encje
JPA EclipseLink. Dokonano również optymalizacji (patrz opis eksperymentu) wykonania przy
302
Paweł Boiński
użyciu ADF Business Components i obiektów perspektyw. Uzyskany rezultat pozostał jednak
nadal gorszy niż konkurencyjne technologie pokazane na wykresie.
3.2.2. Wielokrotny odczyt tego samego elementu
Odczyt wielokrotny tego samego elementu w ramach
pojedynczej transakcji
2,00
1,80
EclipseLink - encjeJPA
Czas wykonania [s]
EclipseLink - JPQL - optymalizacja
1,60
Hibernate - encje JPA
1,40
Hibernate - JPQL - optymalizacja
ADF BC - obiekt encji
1,20
ADF BC - obiekt perspektywy
1,00
0,80
0,60
0,40
0,20
0,00
10000
20000
30000
40000
50000
Liczba obiektów
Rys. 2. Odczyt tego samego elementu w ramach pojedynczej transakcji
Celem kolejnego testu było sprawdzenie, jak zachowują się badane rozwiązania w przypadku
wielokrotnego odczytu tego samego elementu z bazy danych. W ramach testów wykorzystano
encje JPA oraz obiekty encji ADF Business Components (standardowe parametry). Do wykonania
przetwarzania użyto także zapytań JPQL. Zbadano standardowe (bez wskazówek) oraz zoptymalizowane zapytania. Dla biblioteki EclipseLink posłużono się wskazówką:
@QueryHint(name = QueryHints.CACHE_USAGE,
value = CacheUsage.CheckCacheThenDatabase)
która jawnie wymusza użycie pamięci podręcznej przed wysłaniem zapytania do bazy danych.
W przypadku biblioteki Hibernate wykorzystano następujące wskazówki:
@javax.persistence.QueryHint(name = "org.hibernate.cacheable",
value = "true"),
@javax.persistence.QueryHint(name = "org.hibernate.cacheRegion",
value = "tester_region"
gdzie tester_region to nazwa przestrzeni pamięci podręcznej implementowanej przez bibliotekę
EHCache [EHC]. Wykonanie przy użyciu obiektów perspektyw ADF Business Components przebiegało przy parametrze Retrieve from database ustawionym na wartość At most one row.
Uzyskane wyniki (patrz rys. 2) pokazują, że największą szybkością charakteryzują się encje
JPA implementowane przez bibliotekę Hibernate. Niemal równie wydajne są encje JPA EclipseLink oraz obiekty encyjne ADF Business Components. Nieco mniejszą szybkość wykazują
obiekty perspektyw ADF Business Components oraz zapytania JPQL EclipseLink. Najwolniejsze
są zapytania JPQL implementowane przez bibliotekę Hibernate. Należy zauważyć, że we wszystkich opisywanych przypadkach, czas potrzebny na odczyt obiektu jest bardzo mały i w środowisku
produkcyjnym będzie miał znikomy wpływ na wydajność aplikacji.
Analiza porównawcza technologii implementacji warstwy dostępu do danych...
303
3.2.3. Odczyt zbioru obiektów wraz z obiektami powiązanymi referencją
Odczyt zbioru obiektów i referencji, fetch size = 50
120,00
EclipseLink - JPQL
EclipseLink - JPQL + optymalizacja
100,00
Hibernate - JPQL
Hibernate - JPQL - fetch
Czas wykonania [s]
ADF BC - obiekty perspektywy
80,00
ADF BC - obiekty perspektywy z połączeniem
EclipseLink - JPQL - batch
EclipseLink - JPQL - fetch
60,00
Hibernate - JPQL - fetch + optymalizacja
40,00
20,00
0,00
10000
20000
30000
40000
50000
Liczba obiektów
Rys. 3. Odczyt zbioru obiektów i obiektów powiązanych referencją
Odczyt zbioru obiektów i referencji, fetch size = 50
wybrane, najlepsze strategie
30,00
ADF BC - obiekty perspektywy z połączeniem
25,00
EclipseLink - JPQL - fetch
Czas wykonania [s]
Hibernate - JPQL - f etch + optymalizacja
20,00
15,00
10,00
5,00
0,00
10000
20000
30000
40000
50000
Liczba odczytów
Rys. 4. Odczyt zbioru obiektów i wartości powiązanych referencją, wybrane strategie
Kolejny test polegał na odczycie zbioru obiektów za pomocą zapytania z warunkiem nierównościowym (zapytanie o zakres). Jednocześnie odczytywane były zbiory obiektów powiązanych
zależnością referencyjną. Zarówno w przypadku JPA, jak również obiektów encji ADF Business
Components, nie jest możliwe wykonie zapytania zwracającego zbiór obiektów. Wyniki dotyczą
wykorzystania zapytań JPQL oraz obiektów perspektyw. W implementacji EclipseLink, oprócz
standardowych zapytań, wykorzystano zapytania (oznaczone na wykresie słowem optymalizacja)
wzbogacone o wskazówki:
@QueryHint(name = QueryHints.CACHE_USAGE,
value = CacheUsage.CheckCacheThenDatabase)
W przypadku biblioteki Hibernate słowo optymalizacja oznacza użycie wskazówki:
cacheable=true
304
Paweł Boiński
Na wykresie pokazane zostały również czasy wykonań dla zapytań JPQL oznaczone słowami:
• fetch – powoduje wykonanie operacji połączenia relacyjnego i odczyt danych z obu relacji
w pojedynczym zapytaniu,
• batch – powoduje odczyt danych z drugiej relacji po odczycie danych z pierwszej relacji.
Dla obiektu perspektywy ADF Business Components wartość parametru Retrieve from database ustawiono na All at once (przetestowano również wersję z wartością As needed i parametrem In
batches of równym 50, jednak nie zaobserwowano istotnych różnic w czasie wykonania i ze
względu na czytelność wykresu nie zamieszczono na nim wyników tego eksperymentu). Dodatkowo zdefiniowano obiekt perspektywy z jawnym połączeniem relacji (oznaczenie na wykresie:
ADF BC – obiekt perspektywy z połączeniem).
Parametry te nie miały wpływy Uzyskane rezultaty (patrz rys. 3) pozwalają na wyciągnięcie
wniosku o przewadze technologii JPA. Obie przetestowane implementacje wykazują lepszą wydajność w stosunku do ADF Business Components. W przypadku braku optymalizacji zapytań
JPQL, nieco bardziej wydajna jest implementacja Hibernate, podczas gdy przy optymalizacji rolę
lidera przejmuje biblioteka EclipseLink. Zarówno w przypadku JPA, jak również ADF Business
Components, wprowadzone optymalizacje znacząco zmniejszają czas wykonania przetwarzania
(poprzez ograniczenie liczby wykonywanych zapytań). Należy zauważyć, że zoptymalizowana
(z połączeniem) wersja ADF Business Components wygrywa nieznacznie ze standardowymi wykonaniami JPQL z technologii JPA. Na rys. 4 przedstawiono najlepsze wyniki dla każdej z testowanych technologii.
3.2.4. Wstawianie danych
Wstawianie danych, batching, liczba obiektów
wstawianych w pojedyńczej transakcji = 50
7,00
EclipseLink - encje JPA
6,00
Hibernate - encje JPA
Czas wykonania [s]
ADF BC - obiekty encji
5,00
ADF BC - obiekty perspektywy
4,00
3,00
2,00
1,00
0,00
10000
20000
30000
40000
Liczba wstawianych obiektów
Rys. 5. Wstawianie danych
50000
Analiza porównawcza technologii implementacji warstwy dostępu do danych...
305
Wstawianie danych z generowaniem klucza, batching (50),
liczba obiektów wstawianych w pojedyńczej transakcji = 50
160,00
EclipseLink - encje JPA
Czas wykonania [s]
140,00
Hibernate - encje JPA
ADF BC - obiekty encji
120,00
ADF BC - obiekty perspektyw
100,00
80,00
60,00
40,00
20,00
0,00
10000
20000
30000
40000
50000
Liczba wstawianych obiektów
Rys. 6. Wstawianie danych z generowaniem klucza
Następny z opisywanych testów dotyczy problemu utrwalania danych w bazie danych. Przetestowane zostały następujące technologie:
• obiekty JPA dla technologii EclipseLink i Hibernate (wykorzystano metodę persist klasy
EntityManager) przy włączonej opcji hurtowego wykonania operacji DML (ang. batching)
odpowiednio poprzez parametry hibernate.jdbc.batch_size dla Hibernate i eclipselink.jdbc.
batch-writing dla EclipseLink ustawione na wartość 50,
• obiekty encji (metody createInstance klasy EntityDefImpl) i obiekty perspektyw (metody
createRow i insertRow klasy Row) dla technologii ADF Business Components. Podczas
wykonania testów opcja use batching była włączona. Powoduje ona wykorzystanie możliwości wstawienia wielu krotek przy wykorzystaniu jednego polecania.
Nie przeprowadzono testów przy użyciu JPQL, ponieważ język ten nie specyfikuje możliwości
użycia polecenia typu insert. Na wykresach pokazano wyniki dla wykonania, w którym w jednej
transakcji było utrwalanych 50 obiektów. Przeprowadzono dwa testy w zależności od sposobu
generowania wartości identyfikatora: dla jawnie podanej wartości i dla wartości generowanej
z sekwencji w bazie danych.
Uzyskane wyniki (patrz rys. 5 i rys. 6) pozwalają na stwierdzenie, że najwolniejszą technologią
są obiekty perspektyw ADF Business Components. Dotyczy to wstawiania obiektów z i bez generowania klucza. W przypadku wykonania eksperymentu wstawiania krotek bez generowania, klucza najszybszą technologią są obiekty encji ADF Business Components oraz encje JPA w implementacji EclipseLink. Nieco wolniejsze są encję JPA oferowane przez bibliotekę Hibernate.
W sytuacji konieczności generowania klucza przez sekwencję zdefiniowaną w bazie danych, najszybszą technologią są encje JPA w implementacji Hibernate, które nieznacznie wyprzedzają encje JPA dostarczane przez EclipseLink oraz obiekty encji z technologii ADF Business Components.
306
Paweł Boiński
3.2.5. Modyfikacja danych
50,00
Modyfikacja danych, 50 modyfikacji na transakcję,
batching
EclipseLink - encje JPA
45,00
EclipseLink - JPQL
Czas wykonania [s]
40,00
Hibernate - encje JPA
Hibernate - JPQL
35,00
ADF BC - obiekty encyjne
ADF BC - obiekty perspektywy
30,00
25,00
20,00
15,00
10,00
5,00
0,00
10000
20000
30000
40000
50000
Liczba obiektów
Rys. 7. Modyfikacja danych, 50 operacji na transakcję
Kolejny z przeprowadzonych testów posłużył do zbadania wydajności dostępnych rozwiązań
przy modyfikacji obiektów. We wszystkich przypadkach, w przetwarzanych obiektach był zdefiniowany atrybut przechowujący numer wersji zwiększany przy każdej modyfikacji (funkcjonalność oferowana przez badane rozwiązania). Podobnie jak w przypadku wstawiania danych, liczba
operacji modyfikacji w pojedynczej transakcji została ustawiona na 50. Scenariusz modyfikacji
danych zrealizowano dla następujących technologii:
• encje JPA – wykorzystanie metody find klasy EntityManager w celu znalezienia obiektu
a następnie modyfikacja obiektu metodą set*,
• zapytania JPQL – wykorzystanie polecenia UPDATE języka JPQL z operatorem równo-
ściowym. Dla wykonania przy użyciu Hibernate, parametr hibernate.jdbc.batch_size został
ustawiony na wartość 50, natomiast dla biblioteki EclipseLink, parametr eclipselink.jdbc.batch-writing na wartość JDBC, a eclipselink.jdbc.batch-writing.size na wartość
50,
• obiekty encji – wykorzystanie metody findByPrimaryKey klasy EntityDefImpl do znalezie-
nia obiektu, modyfikacja obiektu metodą set* przy włączonej opcji use batching,
• obiekty perspektywy – wykorzystanie metody findByKey klasy ViewObjectImpl i modyfika-
cja obiektu za pomocą metody set*.
Uzyskane wyniki (patrz rys. 7) wskazują na największą wydajność rozwiązania opartego na
zapytaniach JPQL w technologii JPA. Obie implementacje, Hibernate i EclipseLink, wykazały się
podobną efektywnością. Znacznie wolniejsze są obiekty encyjne z technologii ADF Business
Components, które jednak wykonują operację modyfikacji szybciej niż encje JPA. Najwolniejszym rozwiązaniem są obiekty perspektyw ADF Business Components.
Analiza porównawcza technologii implementacji warstwy dostępu do danych...
307
3.2.6. Usuwanie danych
Uuswanie danych, 50 operacji na transakcję, batching
60,00
EclipseLink - encje JPA
EclipseLink - JPQL
50,00
Hibernate - encje JPA
Czas wykonania [s]
Hibernate - JPQL
ADF BC - obiekty encyjne
40,00
ADF BC - obiekty perspektywy
30,00
20,00
10,00
0,00
10000
20000
30000
40000
50000
Liczba obiektów
Rys. 8. Usuwanie danych, 50 operacji na transakcję
Ostatni z prezentowanych testów badał wydajność operacji usuwania obiektów. Tak jak w poprzednich eksperymentach, liczba operacji modyfikacji w pojedynczej transakcji została ustawiona
na 50. Badanie efektywności przeprowadzono dla następujących technologii:
• encje JPA – wykorzystanie metody find klasy EntityManager do znalezienia obiektu, a na-
stępnie usunięcie tego obiektu za pomocą metody remove klasy EntityManager,
• zapytania JPQL – wykorzystanie polecenie delete z warunkiem równościowym języka
JPQL. Dla biblioteki Hibernate parametr hibernate.jdbc.batch_size został ustawiony na
wartość 50, natomiast dla implementacji EclipseLink parametr eclipselink.jdbc.batchwriting na wartość JDBC, a eclipselink.jdbc.batch-writing.size na wartość 50,
• obiekty encji – wykorzystanie metody findByPrimaryKey klasy EntityDefImpl do znalezie-
nia obiektu, usunięcie obiektu metodą remove klasy EntityDefImpl przy włączonej opcji use
batching,
• obiekty perspektywy – wykorzystanie metody findByKey z klasy ViewObjectImp, a następ-
nie modyfikacja obiektu metodą remove (interfejs Row).
Podobnie jak w przypadku operacji modyfikacji obiektów, operacje usuwania są najszybciej
wykonywane przy wykorzystaniu rozwiązania opartego na zapytaniach JPQL w technologii JPA.
Obiekty encyjne ADF Business Components są jednak przy usuwaniu niemal tak samo wydajne.
Wolniejszym rozwiązaniem jest użycie encji JPA, które dla obu badanych implementacji (Hibernate i EclipseLink) dają niemal identyczne wyniki. Ponownie najwolniejszym rozwiązaniem są
obiekty perspektyw dla ADF Business Components.
4. Podsumowanie
Opisane w artykule technologie utrwalania danych oferują szereg funkcjonalności potrzebnych
programiście przy implementowaniu aplikacji. Autor starał się przestawić cechy charakterystyczne
oraz dobre i złe strony omawianych sposobów implementacji warstwy dostępu do danych. Oczywiście niemożliwe jest dokonanie kompletnego przeglądu wszystkich aspektów rozwiązań w ramach tego tekstu. Nadrzędnym celem była analiza wydajności rozpatrywanych technologii.
Zarówno ADF Business Components, jak również biblioteki Hibernate i EclipseLink wykazują
wysoką wydajność w realizacji operacji odczytu, wstawiania, modyfikacji i usuwania obiektów.
308
Paweł Boiński
Za zwycięzcę pod względem wydajności, można uznać bibliotekę Hibernate, której w niewielkim
stopniu ustępuje implementacja JPA dostarczona przez EclipseLink. Można podejrzewać, że przy
skomplikowanych zapytaniach do bazy danych Oracle, w których wymagana jest optymalizacja
dokonywana przez programistę, sytuacja ta mogłaby wyglądać odwrotnie dzięki szerokiemu
wsparciu dla tej platformy przez bibliotekę EclipseLink. Dobrą wydajnością cechują się również
obiekty encyjne w ramach ADF Business Components, jednak w praktycznym zastosowaniu rzadko korzysta się z tych elementów z pominięciem obiektów perspektyw, które okazały się być najmniej wydajną technologią. Spadek wydajności przy użyciu tych komponentów nie był jednak
dramatyczny. Co więcej, z punktu widzenia programisty, ADF Business Components wymagały
znacznie mniejszego wkładu w zakresie optymalizacji. Spowodowane jest to bardzo dobrym
wsparciem środowiska programistycznego JDeveloper, które udostępnia szereg ustawień dla komponentów biznesowych. Większe nakłady pracy są wymagane przy bibliotekach JPA. Ciekawym
aspektem jest również fakt, że podczas eksperymentów, znacznie łatwiej przebiegała optymalizacja dla Hibernate niż dla wywodzącej się z Oracle Toplink biblioteki EclipseLink. W przypadku
losowego odczytu obiektu za pomocą JPA, nie udało się dla tej technologii dokonać skutecznej
optymalizacji mimo, że takie same działania w środowisku Java SE zakończyło się sukcesem.
Przewagą technologii ADF Business Components jest szeroka dokumentacja i integracja ze
środowiskiem JDeveloper, które wspiera automatyzację zadań dla tych komponentów. Za wadę
można uznać wspomniany już brak wykorzystania POJO i złożoność struktur. Technologia ADF
Business Components, mimo wspieranego odwzorowania obiektowo-relacyjnego, znacznie większy nacisk kładzie na relacyjny charakter danych. W przypadku JPA obiektowy charakter aplikacji
znajduje się na szczycie listy priorytetów. JPA jest również wspierane przez większość popularnych środowisk programistycznych. Korzystniejszy jest również sposób licencjonowania.
Na pytanie, jakiej technologii użyć, bardzo trudno udzielić jednoznacznej odpowiedzi. Najbardziej trafne wdaje się być stwierdzenie: to zależy. Warto podkreślić, że ta konkluzja jest subiektywną oceną autora dokonaną na podstawie eksperymentów z wymienionymi technologiami.
W przypadku konstruowania aplikacji, która w istotnym stopniu polega na wizualizacji różnego
rodzaju list i formularzy, dobrym rozwiązaniem może być ADF Business Components. W przypadku, gdy występuje bardziej złożone przetwarzanie biznesowe, warto sięgnąć po technologię
JPA, która oprócz większego stopnia obiektowości, cechuje się również wyższą wydajnością. Problemem w tym wypadku może być natomiast wybór konkretnego dostawcy implementacji JPA.
Teoretycznie ścisłe przestrzeganie standardu JPA powinno pozwolić na bezproblemowe przejście
na implementację od jednego dostawcy do drugiego, jednak doświadczenia wyrażane przez programistów na blogach i forach internetowych przeczą tak optymistycznym założeniom. Równie
istotna może być konieczność wyjścia poza standardowe funkcjonalności JPA w celu uzyskania
najlepszej wydajności.
Bibliografia
[ADF]
Oracle Application Development Framework, http://www.oracle.com/technetwork/developertools/adf/index.html
[EHC]
EHCache, http://ehcache.org
[EJB30]
Enterprise JavaBeans, Simplified API, v 3.0. http://java.sun.com/products/ejb
[EL]
The Eclipse Persistence Services Project, http://www.eclipse.org/eclipselink
[HIB]
Hibernate: Relational Persistence for Java and .NET, http://www.hibernate.org
[HT]
Hibernate Tools, http://www.hibernate.org/subprojects/tools.html
[JEE]
Java EE at a Glance, http://java.sun.com/javaee/index.jsp
[JSR220]
JSR 220: Enterprise JavaBeans 3.0.
[JSR227]
JSR 227: A Standard Data Binding & Data Access Facility for J2EE, http://jcp.org
Analiza porównawcza technologii implementacji warstwy dostępu do danych...
309
[Ora06]
Oracle Application Development Framework Developer’s Guide For Forms/4GL Developers
10g Release 3 (10.1.3.0), 2006.
[Ora10a]
Oracle® Fusion Middleware Fusion Developer's Guide for Oracle Application Development
Framework 11g Release 1 (11.1.1)], 2010.
[Ora10b]
Oracle® Fusion Middleware Java EE Developer's Guide for Oracle Application Development
Framework 11g Release 1 (11.1.1), 2010.
[WTP]
Web Tools Platform, http://www.eclipse.org/webtools/

Podobne dokumenty