Cum mi-a distrus cariera Hibernate aproape
Publicat: 2022-03-11Imaginează-ți că ești un dezvoltator Java și că ești pe cale să începi următorul tău mare proiect. Trebuie să iei deciziile fundamentale care vor rămâne cu tine pentru restul proiectului. Doriți să alegeți cea mai bună abstractizare orientată pe obiect a modelului dumneavoastră de date flexibil, deoarece nu doriți să vă ocupați de SQL simplu. Doriți să susțineți tot felul de date și, în mod ideal, să susțineți tot felul de baze de date.
Răspunsul evident este să folosești doar Hibernate , nu? 90% dintre dezvoltatorii Java ar fi de acord cu tine, dar asta o face decizia corectă?
Să aruncăm o privire la ce poate merge prost dacă utilizați orbește Hibernate doar pentru că este standardul acceptat.
Luați în considerare Monica, un dezvoltator Java. Monica a fost promovată recent la rolul de arhitect și acum este responsabilă de amenajarea stivei de tehnologie pentru un nou produs la compania ei. Ea știe că în lumea Java există un singur instrument bun pentru gestionarea comunicării bazei de date: Hibernate . Hibernate este un standard JPA bine cunoscut și acceptat. Cu toate acestea, este întotdeauna o idee bună să verificați câteva lucruri înainte de a începe un proiect. Din fericire, colegul ei, Ben, îl cunoaște pe tipul potrivit.
Hibernarea sună ca un glonț de argint
Ben - Bună Monica, aș dori să-l prezint pe John. Este un expert Hibernate și te va ajuta.
Monica - Hei John, mă bucur că ai găsit ceva timp pentru mine. Deci, construim următorul nostru lucru important, știi. Plănuim să devenim următorul Facebook sau Google. Zile pline. Va fi uriaș. Absolut fantastic! Toată lumea este atât de entuziasmată! Am fost promovat la rolul de arhitect, așa că acum trebuie să selectez stiva pe care o vom folosi. Singura parte care lipsește este perseverența...
John - Hibernează !
Monica - Da! Exact! Exact ce ma gandeam! Pare o potrivire perfectă și adevărata afacere pentru noi. O adevărată soluție de întreprindere pentru o adevărată problemă de întreprindere, dovedită de piață și cu o istorie lungă. Am auzit atât de multe experiențe pozitive cu el. Totuși, am o problemă cu unul dintre coechipierii noștri; el este total impotriva. Știe multe despre baze de date și îi este frică să nu mai adauge un strat între aplicația noastră și baza de date. Este super inteligent și am nevoie de niște argumente foarte bune pentru a-l convinge că este o decizie bună. Mă poți ajuta cu asta?
John - Desigur! Voi fi fericit sa. Hibernare este, într-adevăr, un instrument remarcabil. Este utilizat pe scară largă în soluții mari și adevărate pentru întreprinderi, cum ar fi băncile. Nu poți greși cu asta. Gândiți-vă la persistență: alegeți Hibernare . Dacă scrieți în Java, aceasta este alegerea perfectă, plus că aveți porturi pentru alte limbi. Vezi câte fișe de post necesită asta!
Monica - Sunt absolut de acord! Am aceleași sentimente despre asta. Într-un proiect anterior, am folosit în mare parte SQL prin JDBC vechi. Ridicol! Stiu! Dar, iată chestia: avem băieți SQL foarte inteligenți în echipă și când au văzut SQL generat de Hibernate au devenit nervoși. Părea urât și imposibil de citit; va fi aceasta o problema in viitor?
John - Uite. Băieții DBA au o perspectivă diferită. Le este frică de Hibernate pentru că pare să le înlocuiască rolul în proiect. În plus, bazele de date au optimizatori de interogări încorporați, astfel încât nu trebuie să vă faceți griji cum vor arăta de fapt acele interogări. Baza de date o va optimiza pentru dvs. Totul este despre dezvoltare rapidă, ceea ce SQL nu poate face.
Monica - Serios?! Nu mai ai de-a face cu SQL? Uimitor! Ultima dată, un DBA a petrecut săptămâni întregi încercând să optimizeze unele interogări. Săptămâni! Oh, mă simt atât de jenat să-ți spun asta, dar știai că folosim... proceduri stocate (râzând). Oh, a fost o mizerie. Îți vine să crezi că proiectul încă îl folosește? Îmi pare atât de rău pentru oamenii de acolo. Mai trebuie să scrie acest cod plictisitor din nou și din nou. Mă întreb dacă este încă un proiect Java sau SQL?
John - Exact asta este diferența dintre o abordare orientată pe obiect și cea relațională. Este o așa-numită nepotrivire de impedanță orientată pe obiect. Hibernarea poate reduce acest decalaj. Dezvoltatorii se pot concentra pe construirea logicii de afaceri. Funcțiile Push fac fericiți părțile interesate și întregul management. Fă lucrurile care contează cel mai mult: afaceri! O mulțime de coduri standard vor dispărea și veți avea o conexiune magică, invizibilă, dar de încredere între logică și date.
Monica - Cooperare reciprocă. Sinergie deplină. Ca și cum baza de date a făcut parte din limbaj încă de la început. Sunt atât de fericit că ajung să fiu un lider al acestui salt tehnologic de credință. Este ca viteza warp în drumul software.
John - Da! Ai prins!
Monica - Doamne, sunt atât de entuziasmată! Mulțumesc, John! Sunt gata!
Dureri de creștere cu soluții neflexibile
Monica - Hei John, îți amintești de proiectul despre care am vorbit anul trecut?
John - Sigur. Cum stă treaba?
Monica - În curând mergem la producție. Totul este bine, dar au apărut câteva întrebări.
John - Sigur, lovește-mă.
Monica - Ei bine, nu ne mai putem genera schema bazei de date de la zero. Care este cea mai bună modalitate de a sprijini modificările schemei fără a pierde date?
John - Ei bine, în primul rând, Hibernate nu este destinat să fie folosit ca instrument de migrare a producției. Folosiți ceva de genul FlywayDB sau Liquibase. Este destul de simplu. Scrieți scripturile de migrare, apoi actualizați modelul de entitate împreună cu mapările Hibernate , astfel încât să rămână sincronizat cu structura actuală a bazei de date.
Monica - Hmm, înțeleg. Am folosit doar migrarea SQL simplă în proiectul anterior.
John - Și asta e bine. Atâta timp cât păstrați modelul de entitate și schema sincronizate, faceți-o cum doriți.
Monica - Înțeleg. Mai e altceva. Ne luptăm mereu cu probleme de preluare leneș/dornic. La un moment dat, ne-am hotărât să facem totul cu nerăbdare, dar pare suboptim și, în plus, uneori nu se poate accesa unele câmpuri pentru că nu există sesiune, sau așa ceva. Este normal?
John - Trebuie să aflați mai multe despre Hibernate . Maparea din baza de date nu este simplă. Practic, există mai multe moduri de a face acest lucru. Trebuie doar să alegi o modalitate care funcționează pentru tine. Preluarea lenevă vă oferă posibilitatea de a încărca acele obiecte la cerere, dar trebuie să operați într-o sesiune activă.
Monica - Încă ne luptăm cu ce motor de bază de date să folosim pentru implementarea finală. Am crezut că Hibernate este portabil, dar avem câteva interogări native care folosesc ceva MS SQL magic și, de fapt, ne-am dori să mergem cu MySQL în producție.
John - Hibernate vă oferă flexibilitate atâta timp cât utilizați criterii detașate sau HQL; orice interogări native vor lega soluția dvs. la baza de date.
Monica - Se pare că trebuie să rămânem la MS SQL atunci. Ultima întrebare: Coechipierul meu a spus că nu există niciun cuvânt cheie „limită” în HQL. Am crezut că glumește, dar nici eu nu l-am găsit. Scuze pentru intrebarea stupida...
John - Într-adevăr, nu există un cuvânt cheie „limită” în HQL. Puteți controla acest lucru prin intermediul unui obiect de interogare, deoarece este specific pentru furnizorul bazei de date.
Monica - Pare ciudat că toate celelalte elemente sunt în HQL. Nu face nimic. Mulțumesc pentru timpul acordat!
Acum piratam împreună soluții în SQL din nou
Monica - John, la început nu aveam de-a face cu SQL, dar acum se pare că trebuie. Nevoile noastre sunt în creștere și se pare că nu există nicio cale de ocolire. Se pare greșit, dar am început să folosim din nou SQL zilnic.

John - Ei bine, nu este greșit. Nu a trebuit să vă concentrați pe baza de date de la bun început. Cu toate acestea, pe măsură ce proiectul crește, este bine să folosiți SQL și să lucrați la optimizarea performanței.
Monica - Uneori petrecem zile întregi căutând erori. Se pare că trebuie să analizăm SQL-ul generat de Hibernate pentru că nu avem idee de ce nu funcționează așa cum era de așteptat și produce rezultate neașteptate. Am întâlnit câteva probleme care sunt bine cunoscute în urmarirea erorilor Hibernate . În plus, este greu să scrieți migrații adecvate, păstrând în același timp sincronizat modelul de entitate. Este consumator de timp, deoarece trebuie să învățăm multe despre elementele interne Hibernate și să anticipăm cum va funcționa.
John - Întotdeauna există o curbă de învățare. Nu trebuie să scrii mult, dar trebuie să știi cum funcționează.
Monica - Lucrul cu seturi de date mai mari este, de asemenea, enervant. Recent, am făcut un import masiv în baza de date și a fost dureros de lent. Apoi am aflat că trebuie să ștergem sesiunea pentru a o face mai rapidă. Chiar și așa, este încă semnificativ mai lent, așa că am decis să-l rescriem ca instrucțiuni SQL simple. Ceea ce este amuzant este că scrierea SQL simplu a fost de fapt cea mai rapidă modalitate de a face acest lucru, așa că am decis să o facem ca ultima noastră opțiune.
John - Importul nu este un proces orientat pe obiecte. Hibernate se concentrează pe design orientat pe obiecte. Rețineți că puteți utiliza întotdeauna interogări native.
Monica - Mă poți ajuta să înțeleg cum funcționează cache-ul Hibernate ? Doar că nu înțeleg. Există câteva cache-uri de primul/al doilea nivel. Despre ce este vorba?
John - Sigur. Este un așa-numit cache la nivel de tranzacție de date persistente. Este posibil să configurați un cache la nivel de cluster sau JVM pe o bază clasă cu clasă și colecție cu colecție. Puteți chiar să conectați un cache în cluster. Dar amintiți-vă că memoria cache nu este conștientă de modificările aduse depozitului persistent de către o altă aplicație. Ele pot fi, totuși, configurate pentru a șterge în mod regulat datele expirate din cache.
Monica - Îmi pare rău, cred că am o zi proastă. Poți explica asta puțin mai mult?
John - Sigur. Ori de câte ori treceți un obiect pentru a save , update , saveOrUpdate sau a-l prelua prin load , get , list , iterate sau scroll , acel obiect este adăugat în memoria cache internă a sesiunii. De asemenea, puteți elimina obiectul și colecțiile acestuia din memoria cache de prim nivel.
Monica - Ei...
John - În plus, puteți controla modurile cache. Puteți folosi modul normal pentru a citi și scrie elemente în memoria cache de nivel al doilea. Utilizați modul get pentru a citi de la al doilea nivel, dar nu puteți scrie înapoi. Folosiți put , care este același cu get , dar nu puteți citi de la al doilea nivel. Puteți utiliza, de asemenea, modul de refresh , care va scrie la al doilea nivel, dar nu va citi din acesta și să ocoliți proprietatea use minimal puts , forțând o reîmprospătare a cache-ului de al doilea nivel pentru toate elementele citite din baza de date.
Monica - Înțeleg. Bine. Lasă-mă să mă gândesc la asta. Oh, e târziu, trebuie să plec. Mulțumesc pentru timpul acordat!
John - Cu plăcere!
Renunțarea la hibernare
Monica - John, am crezut că intrăm într-o nouă eră a dezvoltării software. Am crezut că facem un salt de an lumină. Dar, după patru ani, se pare că încă avem de-a face cu aceleași probleme, doar dintr-un unghi diferit. A trebuit să învăț arhitectura Hibernate , configurare, logare, strategii de denumire, tuplizere, soluții de nume de entități, generatoare de identificatori îmbunătățite, optimizare generatoare de identificatori, uniuni-subclase, marcare XDoclet, asocieri bidirecționale cu colecții indexate, asocieri ternare, idbag, amestecarea polimorfismului implicit cu alte mapări de moștenire, replicarea obiectelor între două depozite de date diferite, obiectele detașate și versiunea automată, moduri de eliberare a conexiunii, interfața de sesiune fără stat, taxonomia persistenței colectării, nivelurile de cache, preluarea leneșă sau dornică și multe, multe altele. Chiar și cu tot ce știu, se pare că am eșuat grav. Este un fiasco software! Eșec suprem! Dezastru! Armaghedon!
John - Stai! Ce s-a întâmplat?
Monica - Am ajuns într-o fundătură. Performanța aplicației noastre este ridicol de lentă! Pentru a obține un raport, trebuie să așteptăm două zile! Două zile pentru a genera efectiv un tablou de bord pentru un client. Înseamnă că în fiecare zi trebuie să ne creștem coada de calcul, în timp ce tabloul de bord devine din ce în ce mai depășit. Expertul nostru DBA a lucrat două luni pentru a optimiza unele interogări, în timp ce structura noastră de baze de date este o mizerie completă. Există dezvoltatori care îl susțin, dar problema este că DBA se gândește în SQL, iar dezvoltatorii petrec zile întregi încercând să traducă acest lucru în criterii detașate sau în format HQL. Încercăm să folosim SQL nativ cât mai mult posibil, deoarece performanța este crucială în acest moment. Oricum, nu putem face mare lucru, deoarece schema bazei de date pare să fie greșită. S-a simțit corect din perspectiva orientată pe obiect, dar pare ridicol din cea relațională. Mă întreb: cum s-a întâmplat asta? Dezvoltatorii ne spun că schimbarea structurii entităților va fi un efort masiv, așa că nu ne putem permite asta. Îmi amintesc că în proiectul anterior a fost o mizerie, dar nu am ajuns niciodată la un punct atât de critic. Am putut să scriem o aplicație complet diferită pentru a lucra cu datele. Acum, este riscant să modificați acele tabele generate, deoarece este foarte greu să vă asigurați că modelul de entitate se va comporta întotdeauna corect. Și asta nu este nici măcar partea cea mai rea! Pentru a crește performanța, trebuie să rezolvăm nu numai problemele bazei de date, ci și problemele cu întregul strat dintre baza noastră de date și aplicație. Este copleșitor! Avem acești tipi noi, știi, consultanți. Ei încearcă să extragă date, să le pună într-un alt spațiu de stocare și apoi să efectueze calcule din exterior. Totul ia prea mult timp!
John - Nu știu ce să spun.
Monica - Îl vezi pe John; Nu vreau să te învinovăţesc. Am ales Hibernate pentru a rezolva toate aceste probleme, dar acum am învățat că nu este un glonț de argint. Prejudiciul a fost făcut și este ireversibil. De fapt, aș vrea să vă întreb ceva: mi-am petrecut ultimii patru ani ai carierei ocupându-mă de chestii Hibernate . Se pare că nu am viitor la compania mea actuală. Mă puteți ajuta?
Deci, care este lecția învățată?
John - Hei, Peter, lasă-mă să o prezint pe Monica.
Peter - Hei, Monica! Construim noul nostru următor mare lucru, știi. Va fi uriaș! Vrem să fim ca Uber! Știi poate cât de perseverență...
Monica - Nu hibernează !
Învelire
Monica este expertă în Hibernate . Cu toate acestea, Hibernate în acest caz a fost o decizie greșită. În momentul în care a descoperit că soluția ei se transforma într-o problemă mai mare decât originalul, a fost cea mai mare amenințare la adresa întregului proiect.
Datele sunt scopul central al aplicației și, vă place sau nu, afectează întreaga arhitectură. După cum am aflat din poveste, nu utilizați Hibernate doar pentru că aplicația dvs. Java folosește o bază de date sau din cauza dovezilor sociale. Alegeți o soluție care să includă flexibilitate. Există o mulțime de opțiuni pentru wrapper-uri JDBC robuste, cum ar fi JdbcTemplate sau Fluent JDBC Wrapper. Alternativ, există și alte soluții puternice, cum ar fi jOOQ.
