Nedostatky JPA

Nenechte se zmást názvem, myslím si, že JPA je dobrý a užitečný standard. Nicméně je nutné mít na mysli, že je to jenom standard, tudíž s sebou nese všechny klady i nedostatky, které jsou se standardy obvykle spojeny.

JPA vznikalo v situaci, kdy bylo na trhu několik dodavatelů O/R mapovacích nástrojů. Mnozí z nich se i na jeho vývoji podíleli. Nemůže nás proto překvapovat, že JPA pokrývá jenom podmnožinu průniku funkčností, které existující nástroje umožňovaly. To co uměl například Hiberante oproti Toplinku se do standardu prostě dostat nemohlo. Platí to samozřejmě i naopak. V tomto článku, bych chtěl shrnout pár věcí, které mi v JPA chybí.

Vlastní typy (UserTypes , Custom types)

JPA umožňuje ukládat jenom následující typy:

Java primitive types; java.lang.String; other Java serializable types (including wrappers of the primitive types, java.math.BigInteger, java.math.BigDecimal, java.util.Date, java.util.Calendar, java.sql.Date, java.sql.Time, java.sql.Timestamp, user-defined serializable types, byte[], Byte[], char[], and Character[]); enums; entity types and/or collections of entity types; and embeddable classes

Na první pohled by se mohlo stát, že to stačí. Nicméně co dělat, když máme například položku typu java.net.URL a chceme ji uložit jako String? Pomocí JPA se vám ji podaří uložit jedině v serializované podobě. Zajímavou diskuzi k tomuto tématu najdete na TSS.


Criteria API

Criteria API je funkčnost Hibernate, které se hodí, když skládáme databázový dotaz za běhu. Například, pokud máme formulář pro uživatelsky definovaný filtr. Bez criteria API musíme skládat dotaz do řetězce jen proto, aby si ho mohl JPA provider vzápětí naparsovat a složit z něj SQL řetězec. To se mi zdá trochu postavené na hlavu.


Jednosměrné one-to-many vztahy bez join tabulky

Více na jednom z předchozích příspěvků. Například Toplink Essentials tyto vazby opravdu nepodporuje.

Zabíjení sirotečků (delete-orphan)

Umožňuje nám automaticky mazat prvky, které jsme odebrali z one-to-many asociace. Mám-li například třídu klient, která obsahuje kolekci adres, delete orphan mi zajistí automatické smazání adresy poté, co ji odeberu z kolekce. Jelikož JPA tuto funkcionalitu nepodporuji, je nutné adresy mazat ručně, což v některých situacích může být dost komplikované. Více se můžete dočíst v dokumentaci k Hibernate.


Nastavení pro ladění výkonu

Například BatchSize a další. Ladění výkonu je věc, na kterou obvykle v aplikacích typu HalloWord nenarazíte. Pokud ovšem budete psát reálnou aplikaci, bez těchto funkcionalit se neobejdete. A JPA vám kromě možnosti psaní si vlastního SQL mnoho pomoci nenabídne.

Další věci, které nejsou pokryty standardem, ale například Hibernate je umožňuje, můžeme najít na v dokumentaci k Hibernate Extensions.

A co nám z toho plyne? JPA udělalo velikou práci v tom, že sjednotilo metadata pro O/R mapování. Pokud vám nevadí psaní metadat v anotacích, určitě je dobré tento standard používat. Zajistíte si tím snazší přenositelnost na jiného JPA providera. Je ale nepravděpodobné, že se vám podaří napsat a provozovat aplikaci čistě v JPA, aniž by byla závislá na konkrétní implementaci. Pokud se tedy vzdáme iluze o snadné přenositelnosti, je podle mého názoru nejrozumnější používat JPA jenom na definici metadat. Pro DAO vrstvu bych už používal implementaci, na kterou už jsme tak jako tak vázáni. Tzn. v případě Hibernate by to byl Springovský HibernateTemplate, který mi umožní používat HQL a Criteria API.

A to je právě to krásné na JPA, nenutí mě brát všechno nebo nic. Dává mi svobodu vybrat si jak moc ho chci používat. Mohu si vybrat jestli ho chci „degradovat“ jen na formu zápisu metadat nebo jestli mi jeho omezení stojí za tu iluzi snadné přenositelnosti.

2 Responses to “Nedostatky JPA”

  1. Roman Dagi Pichlik Says:

    To je zajimavy point, nikdy me nenapadlo premyslet o JPA tak, ze bych si "vzal" pouze cast. Dokonce to dava smysl mit mapovani nezavisle na implementaci. Mimochodem budeme nahravat podcast o ORM, nechcete se pridat jako specialni host tohoto tematu?

  2. Michal Bocek Says:

    Trefne a celkom dobre zhrnutie malych nedostatkov, ale je to predsa specifikacia. UserTypes sa mi podarilo nahradit embeddable classes - trosku neohrabane ale da sa. Ku tym anotaciam, stale je moznost pouzit xml (orm.xml).