Java mapování – Orika vs. Dozer

Úvod

Při analyzování propustnosti webových služeb jednoho projektu zjistil kolega Honza Kovář, že mapování objektů pomocí knihovny DOZER zabírá při zpracování požadavku cca. třetinu času. Tomáš Hofman poté přišel s návrhem vyzkoušet knihovnu ORIKA, která by měla být dle internetových diskuzí znatelně rychlejší.

Vytvořil jsem tedy projekt, kde jsem různé způsoby mapování implementoval přes společné rozhraní IEntityMapper. Zároveň jsem jako mapovací entitu použil skládaný objekt Customer s použitím dědičnosti.

API

Veškeré mapování je realizováno pomocí rozhraní IEntityMapper:

Mapované entity byly následující:

Jedná se pouze o příklad, zdrojový kód se nachází zde: github.com.

Implementace

DOZER

Jako první implementaci jsem použil DOZER. Ten se u nás v mém současném zaměstnání používá poměrně dlouho (od cca. 2008) a osobně s ním mám dobré zkušenosti. Implementace mapování vypadá následovně:

Příklad konfigurace:

Konfigurace mapování entit:

DOZER používá pro mapování reflexi a poskytuje poměrně bohaté možnosti na konfiguraci mapování. Mám zkušenosti, že problémy s touto knihovnou jsou zpravidla způsobené neznalostí. Nicméně zrovna u tohoto příkladu jsem narazil na problém. Pokud je v mapování předka použitá formule this (AbstractEntity <> EntityRootTO), tak v potomkovi se to už ignoruje. CustomerAddress není v tomto případě možné podědit od AbstractEntity. Předpis address > this by se již neprovedl.

Výhody Nevýhody
Odstínění výkonného kódu od mapovacího balastu (Boilerplate code) Pomalé
Snadná a přehledná konfigurace ve formě XML Nelze jednoduše krokovat

ORIKA

ORIKA pro mapování reflexi nepoužívá. Pro mapování si vygeneruje pomocné třídy. Konfigurace se provádí na úrovni java kódu.

Implementace mapperu:

Konfigurace kontextu:

Konfigurace mapování:

Jak DOZER tak ORIKA poskytují možnosti k definování vlastních konvertorů. Přepis implementace z DOZERu na ORIKAu je poměrně snadný.

Výhody Nevýhody
Odstínění výkonného kódu od mapovacího balastu (Boilerplate code) Konfigurace v java kódu
Rychlost Nelze jednoduše krokovat

CUSTOM

Poslední testovanou možností je vše mapovat ručně. Samozřejmě i tady se doporučuje skrýt mapování za nějaký interface. Při vytváření tohoto příkladu jsem si uvědomil, jak je ruční mapování bolestné. Jen ošetřování mapování proti NullPointerException u složitějších objektů je vysloveně tragédie. Výsledky testů však můžou tuto mizérii potlačit.

Příklad implementace mapperu:

Konfigurace kontextu:

Ukázka mapování:

Výhody Nevýhody
Jednoznačně rychlost Boilerplate code
Možnost krokovat mapování Vysoká náchylnost na chyby (NPE)

Závěr

U výkonnostních testů se mapovalo 100.000 různých objektů DOMAIN > DTO. Před spuštěním testů bylo pro inicializaci mapovacího frameworku spuštěno jedno zahřívací mapování.

Výsledky
MAPPER TIME 1 (ms) TIME 2 (ms) TIME 3 (ms) TIME 4 (ms) TIME 5 (ms) AVG (ms)
DOZER 11923 12129 12001 11724 11534 11862.2
ORIKA 5752 5308 5343 5767 5534 5540.8
CUSTOM 600 640 544 622 646 610.4

mapping_performance_chart

 

Nezávisle na použitém způsobu mapování je vždy nezbytné pokrytí mapování unit testy!

Zdroje

Leave a Reply

Your email address will not be published. Required fields are marked *