18. září 2011

Proč nechci použít Hibernate na dalším projektu

Minulý týden se mě kolega zeptal, zda bych použil znovu Hibernate na dalším projektu? Já jsem mu po krátkém zamyšlení řekl, že již ne, že bych Hibernate (a obecně žádné jiné ORM řešení) nepoužil. Následovala diskuze, kde jsem se snažil obhájit mojí odpověď:

  • ORM nástroje se snaží vývojáře odstínit od konkrétního úložiště dat, snaží se vývojáře držet pouze v objektovém světě bez ohledu na to, že nejčastěji ukládáme data do relačních databází. Je naivní si myslet, že napíši kvalitní aplikaci bez znalostí databází a SQL.

  • ORM nástroje (pozn. konkrétně Hibernate, protože s ním několik let pracuji, ale myslím si, že to lze zobecnit pro všechny ORM nástroje) přidávají do projektů další velkou složitost, nároky na znalosti a zkušenosti. Toto má vliv na spoustu dalších věcí - výběr vhodných lidí do týmu, architektura systému, větší pravděpodobnost chyb, plnění termínů atd.

  • znalost SQL mi přijde natolik rozšířená a základní, že v tomto nevidím další znalostí zátěž pro vývojáře

  • používání ORM odstiňuje vývojáře od přímé práce s databází, což často vede k tomu, že vývojáři vůbec vlastně nevědí, jak jsou určité operace náročné, kolik se vlastně výsledně musí zavolat SQL dotazů, aby se jedna Hibernate operace vykonala

  • Hibernate přináší do vývojového týmu prvek náhodnosti, špatné říditelnosti - pokud vím, že mám napsat 3 dotazy přes JDBC, tak je to tak jasná a ohraničená věc, že není co dalšího řešit. Místo toho implementovat DAO pomocí Hibernatu, to moc jasné být nemusí - nikdy člověk neví, na čem se může zaseknout nebo jak se bude Hibernate v určitých kritických stavech chovat.

  • při porovnávání JDBC vs. ORM přístupů je potřeba také zmínit, že databáze často mnohonásobně přežijí aplikace, které je využívají. Technologie pro server a klienta se mění mnohem rychleji než relační databáze a jazyk SQL. Z tohoto pohledu je základem správný návrh databáze bez ohledu na to, jakou architekturu pak aplikace bude mít.

  • kolikrát se na projektu měnila databáze? Možná lepší otázka - stalo se již někomu, že se během projektu měnila databáze? Když pominu vývoj aplikací pro více databází, tak naopak si myslím, že napojení na konkrétní databázi mi nabízí mnohem více než když jsem odstíněný přes ORM.

  • ladění složitějších HQL nebo Criteria dotazů moc nejde a já osobně jsem vždy skončil u SQL. Někdy postupuji i naopak - pomocí SQL si vyzkouším, že daný dotaz je možné vytvořit, a že je správný a pak ho přepisuji pomocí Hibernatu.

Myslím, že nejsem sám, kdo má dnes podobný názor k této problematice jako já, viz např. článek Problems with ORMs jako jeden z nich.

Základní otázkou ale zůstává, co tedy jiného místo toho? Mě zde bohužel chybí osobní zkušenost, ale určitě bych se vydal cestou přes JDBC, tedy jako vhodné řešení mi přijde použití MyBatis nebo Spring JDBC nebo Spring Data nebo to celé nějak zkombinovat dohromady.

15 komentářů:

karl řekl(a)...

V nasi aplikaci podporujeme 2 databaze (PostgreSQL a Oracle) pres iBatis. A diky XML, ruznym mapam atd... je udrzovani docela peklo. Balast okolo zneprehlednuje samotne SQL dotazy.

prema řekl(a)...

Ahoj Petre,
nemyslim si, ze ORM nastroje tady jsou proto, aby umoznily vytvaret aplikace bez znalosti databazi a SQL; sam pises, ze znalost SQL ti prijde rozsirena a zakladni.

Hlavni vyhodu odstineni vidim ve snadnejsim refaktoringu a testovani.

Pokud zavedu konvence, napriklad, ze hibernate entita se nikdy nedostane vne session, zamezim nahodilosti a lazy initialization exception. Potom jak rika muj kolega, Hibernate je jen takovy podvozek, ktery ti usnadnuje praci.

Souhlasim, ze vzrusta komplexita a naroky na lidi, ale kdyz uz ty zkusenosti jednou mam, pripadne mi nepouziti Hibernate ve vetsi "relacne-databazove" aplikaci jako cesta zpet.

Augi řekl(a)...

Stoprocentní souhlas. Nemohl jsem uvěřit vlastním očím, když jsem se v knize PoEAA od Fowlera dočetl, že ORM má odstiňovat vývojáře od nutnosti znalosti SQL. Copak si člověk, který nezná SQL, může vůbec říkat vývojář? Pokud ano, tak to s sebou nese následky, o kterých jsi psal (neví, jaká je složitost operací atd.).

Přesto si ale myslím, že ORM mají své místo - z hlediska CQRS mohou dobře posloužit k implementaci "crud" (ne-event sourced) "domain repositories", tedy repositories, které poskytují jen Add, Update, Remove a GetById. Tedy žádné dotazování. Tak je využijeme k tomu, co ORM umí dobře a ušetří nám tak práci - sledování stavu objektu, implementace "identity map".

Pro "reporting" část (tedy veškeré non-id dotazy) bych použil úplně jiný přístup k datům, pravdědopobně něco jako custom "query objects" (ne specifikace, které poskytuje ORM).

Výhoda tohodle přístupu je to, že v případě potřeby je možné si naimplementovat onu jednoduchou "domain repository" sám, např. když se pracuje vůči nějakému nerelačnímu úložišti, kde není ORM dostupné.

Jan Šeda řekl(a)...

Taky souhlas, úplně to vystihuje moje zkušnosti.

Martin Podval řekl(a)...

Nemohu uplne souhlasit. Hibernate je velmi mocny nastroj a to zda ho pouzit ci nepouzit je vec zhodnoceni prospsnosti v ramci projektu. Pokud znas dobre Hibernate a umis ho spravne vyuzit, dokazes navrhnout a implementovat aplikaci v radove kratsi dobe nez rucne. Jeho pouziti ci nepouziti na projektu zavisi tedy na vyvojarich, projektu a cilove databazi. Neni to pouze o zmene databaze ale take o tom, zda neni potreba podporovat vice databazi. Hibernate obsahuje spousta skvelych veci jako je session/first level cache ci second level cache, batchove ci multiquery veci. Hibernate se urcite nesnazi developera odtrhnout od znalosti databaze, ale snazi se praci nad databazi unifikovat - proto nabizi HQL/criteria atd. - to se mu urcite velmi podarilo. Problem je, ze lide si mysli, ze nemusi rozumnet databazi, coz je grandiozni omyl. Pokud nekdo nerozumi databazi a modelu, ktery se snazi ukladat, jednoznacne vznikne nepouzitelna a neskalovatelna vec. Tohle cele nebezpeci je nutny zvazit na zacatku projektu a podle toho se potom rozhodnout. Ja bych Hibernate v ramci okolnosti pouzil pro vetsinu projektu, pouze bych se jako "vlastnik" persistentni vrstvy snazil expozovat veci nahoru pro dalsi developery podle jejich znalosti. Hloupy priklad: pokud lide uplne nerozumi lazy loadovani, nebudu ho pouzivat a kazdy si bude muset napsat svoje query sam presne pro dane pouziti. Vyhnu se tim napr. select n+1 problemu. atd. Spis vidim problemy Hibernatu v rychlosti materializace a obracenem principu, kdy si clovek navrhne slozity model a hibernate mu ho (bohuzel) umoznuje persistit ikdyz databazove je spatne. Pro poradne aplikace je potreba to delat obracene.

Anonymní řekl(a)...

Dobre napsane.
Po cca 5ti letech na ruznych projektech s JPA/Hibernate mam uplne totozny nazor. Do posledniho detailu.

MyBatis mi prijde vyborny, ve spojeni se Springem (podpora jako-EJB propagovani transakci pres anotace) to je parada.
Skoda jen, ze ORM je brano za standard a clovek s tim 'musi' delat.

Jeste jako poznamka, pred par dny jsem se dostal na stranky jOOQ
http://sourceforge.net/apps/trac/jooq
a prijde mi to docela zajimavy na nektere veci, ale jsem to jeste nezkousel.

Marian

Michal Neuwirth řekl(a)...

Ja bych to rekl asi tak, ze ORM je stejny "podvod" jako .NET ci J2EE a dalsi frameworky. .NET vznikl proto, aby se urychlil vyvoj aplikaci pro Windows a zaroven, aby kazdy "pseudo" programator mohl pro Windows mohl programovat. Znalost vyvoje pro OS se zmenila ve znalost .NET (ci jineho) frameworku. Kolik soucasnych .NET vyvojaru ma vubec tucha o tom, co se deje vespod? Kdo z nich je schopen udelat veci, jez vyzaduji P/Invoke atd.? Bohuzel ORM vede stejnym smerem. Snazi se "urychlit" vyvoj DB aplikaci a zaroven umoznit "pseudo databazovym odbornikum" delat DB aplikace. A stejne jako u .NETu se lidi budou soustredit na znalost daneho ORM namisto znalosti vlastniho DB.... Na druhou stranu, pokud potrebuji udelat nejakou pidi-aplikaci v co nejkratsim case, kde nehrozi problemy s rychlosti atd., tak je ORM dobry sluzebnik.

Anonymní řekl(a)...

Souhlas s clankem.

Kdyz sleduju projekty, tak se stejne vzdy jedna o vecevrstvou architekturu, takze implementace hiernate je v jedne vrstve, a kdyz si porovnam narocnost vytvoreni rucniho SQL a tvorby hibernate tak to vychadzi na stejno, navyse hibernate ma spominane problemy s tim ze je to framework a obcas neco nejde udelat nebo jde udelat hodne blbe a SQL to umi lip.

Casto se stretavam z nazorem ze hibernate ma vyhodu v tom ze se pracuje jenom s value-object, ale kdyz mate vicero vrstev, stejne pracujete na teto urovni a uspora neni zasadni. o tom ze nativni SQL je vykonejsi, mate nad nim kontrolu a aplikace ma lepsi vykon ani nemluvne.

Kamilos řekl(a)...

Myslím že by to chtělo celý problém popsat mnohem precizněji. V názvu článku se hovoží o Hibernate a najednou se mávnutím proutku hovoří obecně o ORM.

Naprosto souhlasím, že Hibernate není triviální na naučení a určitě není jednoduchý pro začátečníky.

Ale shodit tím kompletně ORM? A jak by si to tedy chtěl udělat?

Java jsou objekty. Databáze jsou relace. Asi není překvapení, že zkratka ORM znamená objektově relační mapování. No ale přece i když napíšu SQL dotaz, projdu ResultSet a výsledky uložím do Java objektu, tak také ale dělám ORM!

Rozdíl je, že Hibernate dělá ORM automaticky, jinak ho udělám ručně.

Závěrem, tvrdit tedy "ORM bych nepoužil" nedává smysl.

Otázka zní, "budu dělat ORM ručne, použiji na to nástroj. A pokud ano, tak který?".

Bohužel článek mi přijde spíš o tom šokovat, protože kritizovat ORM a Hibernate vždy zabere. Zamyšlení se nad základními pojmy mi ale bohužel chybí.

Anonymní řekl(a)...

Zdravím, nějak mi v této debatě chybí, čemu má výsledná aplikace sloužit, tj. proč vůbec vzniká požadavek na nějakou aplikaci, který nám, programátorům, generuje peníze. Používají se při tom slova "doména", "byznys logika" atp. Marná sláva, nejlépe se to popisuje objektově a v UML, BPMN apod. A v tomto je (klasické) SQL brzda. ORM je jen marná snaha zachránit SQL. Řešení je ukládat (persistit) objekty přímo (nativně). Není to sice tak multiplatformní jako SQL, ale koho to zajímá? Do databáze (přímo) stejně nemá co kdo lézt. Od toho má být aplikační server. Aplikační logika totiž stejně do úložiště dat nepatří. Uložené procedury ala-SQL na aplikační server nemají šanci... Zkuste DB4O :-) a replikace ;-)

Anonymní řekl(a)...

Mam rad MyBatis i Hibernate.
Pouzival jsem na ruznych projektech oba a nemuzu ani o jednom z nich rici ze je lepsi nez ten druhy.
Oba dva samozrejme predpokladaji znalost SQL.
Dulezite je v jake situaci pouzit ktery.

Hibernate se osvedcuje, kdyz vyvijim na zelene louce, mame zcela pod palcem domenovy model. Pak je opravdu jednoduche vyvinout aplikaci nad in-memory DB, vcetne integracnich testu. Nemusi se psat zacne create scripty. Prepnuti na produkcni DB je pak konfiguracni zalezitosti, doplnenou o nakonfigurovani nekolika indexu na kriticke operace.

iBatis bych si vybral, pokud dedim databazove schema nebo se pouzivaji ulozene procedury.

NoxArt řekl(a)...

Používám Doctrine2 a nejsem nijak extra ostřílený vývojář. Imho dost záleží od projektu, rozsahu projektu a očekávání, které kdo od ORM má...

Třeba osobně údajné odstínění od SQL vůbec neřešim, což jaksi odbourává spoustu mnoha lidmi prezentované nevýhody - dívám se co se generuje za SQL, za databázi, zoptimalizuji, pohoda

Třeba body 1-4:
1) vývojář musí stejně umět SQL + 3) skoro všichni umí SQL => kde je tedy problém?

4) To už je hodně extrémní lenost, nepodívat se do logu dotazů


Samozřejmě, s tím pohodlím ORM přichází cena ... zde jsou zmíněny jen ceny, každý ať si to tedy zváží

Třeba pro nevelké projekty pro malý tým mi ORM přijde v pohodě. Doctrine2 nemá myslim moc požadavky na schéma databáze a stejně -> samo generuje v podstatě tak, jak jsem to dřív navrhl sám. Pro většinu stránek si vystačím s 1-3 selekty (DQL ~ HQL, pravda ale nic složitého), generuje to, co bych napsal v SQL ... jenom mi to přijde paradoxně naopak více náročnější na CPU, než tu DB

anon47 řekl(a)...

V poslední době se ukazuje, že velice zajímavá je varianta: Event sourcing + všechna data v paměti. A není to problém, protože se dají koupit boxy s 1TB paměti.

juzna.cz řekl(a)...

Mam opacne zkusenosti, delal sem na projektu co se postupne predelaval na ORM, a s tim puvodnim byla bolest pracovat, oproti s ORM krasa. Ale mozna za to mohl ten stary projekt, ze byl proste "starej".

půlpitel řekl(a)...

Kamilos: kdyz autor psal o ORM, tak mel na mysli ORM frameworky. Rekl bych, ze vsichni pritomni to pochopili :)