2009-09-20

Využití UJO v Hibernate

Tento článek se zabývá využitím UJO objektů v prostředí ORM frameworku Hibernate. Jaký může být důvod nahradit klasické POJO objekty invazivnější alternativou? Výhodu vidím především v možnostech snadnějšího zpracování výsledků pomocí užitečného API a k tomu přijde vhod i jisté navýšení výkonu některých typů HQL dotazů.

Úvodem bych rád rozptýlil mýtus, že za UJO objekty je schovaná neprůhledná magie. UJO může být každý objekt, který implementuje interface Ujo se čtyřmi metodami. Existuje více implementací, ale nyní si popíšeme QuickUjo obsažený v UJO Frameworku 0.91, který se vyznačuje snadnou použitelností a velkou rychlostí čtení i zápisu ve srovnání s Java reflexí.

Jak ten QuickUjo tedy funguje, ptáte se? Uvnitř toho objektu je schovaný jediný atribut obsahující pole objektů s délkou odpovídající počtu atributů objektu. Protože pro přístup k hodnotám objektu slouží konstanty zvané UjoProperty, můžeme každé takové property přiřadit index ukazující na jednu buňku z tohoto pole. Pokud tedy máme instanci UJO + UjoProperty, tak můžeme snadno získat i hodnotu, o přetypování se pak postará implementace UjoProperty. Není to jednoduché?

Typický příklad kódu pro čtení hodnoty:
String name = Person.NAME.getValue(person);
alternativní příklad použití rozšířené implementace QuickUjoMid:
String name = person.get(Person.NAME);

Zajímavé bude srovnání výkonu UJO a POJO objektů v prostředí ORM frameworku Hibernate, potřebujeme však znát, jak se ty UJO mapují. Můj kolega Tomáš Hampl, napsal elegantní řešení založené na implementaci rozhraní PropertyAccessor, které je nyní k dispozici v UJO Frameworku 0.91. Vlivem nedokonalosti Hibernate je třeba implementovat ještě odpovídající gettery, ty však Hibernate používá pouze při startu aplikace. Nic nám ovšem nebrání dopsat si také settery pro vlastní pohodlí a objekty používat jako běžné POJO. Ukázka hotové implementace UJO je tady.

Specifikace alternativního accessoru v HBM souboru vypadá takto:
<hibernate-mapping
default-access = "org.ujoframework.hibernateSupport.UjoPropertyAccessor"
... >


Pokud se výdáte cestou anotací, použijte
@org.hibernate.annotations.AccessType( "org.ujoframework.hibernateSupport.UjoPropertyAccessor" )

a na místo fieldů anotujte gettery.
Podívejte se, jak dopadly benchmark testy:

Hibernate akcePOJO [sec]
UJO [sec]Poměr
INSERT11,3712,310,92
SINGLE SELECT0,580,521,13
EMPTY SELECTS152,5394,301,62
MULTI SELECT169,5294,721,79
UPDATE3,693,750,99
DELETE210,14140,271,50

Kompetentní výklad výsledků přenechám raději odborníkům na Hibernate v diskusi. Popis testovacího prostředí najdete tady. Zdrojový kód testu lze stáhnout na SourceForge.

Na závěr bych rád uvedl na pravou míru, že reálné navýšení rychlosti se projeví především u rychlých a dobře indexovaných SQL dotazů s přiměřenou mírou aplikační logiky. Pokud je odezva na SQL dotaz pomalá a nebo výsledek dotazu podléhá náročnému zpracování, úspora rychlosti se v kontextu ostatních událostí může vytratit.

Odkazy:

2009-08-31

Ujorm verze 0.90

Byla uvolněna stabilní verze ORM modulu UJO Framework 0.90. Hlavní změny od poslední beta-verze jsou:

  • další zrychlení dotazu typu SELECT
  • změna pracovního názvu UJO-ORM na finální Ujorm
  • podpora nových databází Oracle a Firebird
  • zobecněné API
  • oprava některých menších chyb

Nová aktualizovaná prezentace ORM je dostupná v angličtině zde.

2009-08-12

UJO-ORM: doplněné testy

Úvodem bych rád poděkoval všem za komentáře k minulému příspěvku i když je pravda, že někteří mě příliš nešetřili :). Srovnání s konkurencí je nezbytné, já jsem si pro tento účel dovolil vybrat Hibernate, neberte to, prosím, osobně.

Na základě vašich připomínek jsem doplnil test SINGLE SELECT, který čte velký počet DB řádků z jedné tabulky. Dále jsem doplnil test zvaný EMPTY SELECT pro opakované dotazování nad tabulkou s prázdným výsledkem. Žádný z uvedených testů nereprezentuje zpravidla chování reálného serverového řešení a bezpochyby ani ten původní test (MULTI SELECT) není optimální.

AkceUJO-ORM Hibernate
SINGLE SELECT0.500 sec
0.833 sec
EMPTY SELECT1.305 sec  155.066 sec
MULTI SELECT21.715 sec172.258 sec


Výsledky naznačují, že úzkým hrdlem Hibernate může být parsování HQL dotazu. Připomínám, že případné zapnutí "Hibernate Query Cache" bude významné jen pro případ stejných parametrů dotazu.

Odkaz na aktualizované testy je zde.

Pavel

2009-07-26

Nové ORM 8x rychlejší než Hibernate

Dovoluji si představit Vám nový open source ORM framework pro jazyk Java s názvem UJO-ORM, který je postaven na architektuře UJO objektů. Nové ORM řešení vzniklo ve snaze usnadnit vývoj perzistentní vrstvy, nicméně výkonnostní testy ukazují, že dotazy typu SELECT jsou osmkrát rychlejší ve srovnání s Hibernate. Další zajímavé vlastnosti jsou například kontrola typu parametrů v dotazu, malé paměťové nároky a miminální velikost celého řešení.

Úvodní prezentace je zde:
http://ujoframework.org/prezentace/

Výsledky benchmark testů jsou v následující tabulce, podrobnosti o testování najdete v prezentaci:
AkceUJO-ORM Hibernate
META-DATA0.2821.562
INSERT10.14011.407
SELECT22.016175.234
DELETE64.625206.813

ORM home page:
http://ujoframework.org/orm/

Odkaz na zdrojový kód testů je zde:
https://sourceforge.net/projects/ujoframework/files/

Oficiální představení ORM modulu je plánováno na září 2009, nicméně už teď uvítám všechny Vaše podněty a připomínky. V případě zájmu o spolupráci kontaktujte autora na adrese: ujoframework(zavináč)gmail.com .


Pavel