Prikazani su postovi s oznakom Hibernate. Prikaži sve postove
Prikazani su postovi s oznakom Hibernate. Prikaži sve postove

subota, 28. siječnja 2012.

Hibernate i Spring MVC integracija

Napokon! Kažem ja. Napokon malo zabavniji dio cijele ove priče. Napokon ću se dotaknuti teme hibernatea i spring mvc-a, ili kako mi je netko nedavno rekao - to je pod mus!
Hibernate je briljantan ORM, Spring MVC je briljantan framework za web i šta nalaže logika - da se to dvoje spoje. I to rade super, štoviše jedno drugoga nadopunjavaju.

Treba od nekud početi. Zašto uopće sve to? Ako niste spavali zadnjih 10.godina, trenutno je vrlo teško naći web stranicu koja svoj sadržaj ne sprema u bazu podataka. Naravno iznimke postoje i uvijek će ih biti, ali ako generaliziramo, ne znam tko više uopće odabire obične HTML stranice? Odgovor je vrlo lak - moderni hrvatski "biznismen" koji je dao nešto novaca susjedovom malom da mu napravi web stranicu za njegov "biznis". Ali čak i svaki napredniji "susjedov mali" bira bazu kao osnovu za spremanje podataka. Razlog je jednostavan - lakše je! Podatci su dostupni zauvijek, ti podatci se mogu pretraživati, raditi nešto s njima, a da ne pričam koliko je lako dodavanje novih sadržaja kad se ima iole dobar cms. Imajući sve to u vidu, vrijeme je da se vratim na naslov posta.

Ima nekoliko načina na koji se može naučiti ova tema, pa ću i nabrojati nekoliko:
  • Službena dokumentacija Spring frameworka (http://static.springsource.org/spring/docs/2.5.x/reference/orm.html)
  • Tutrorijali na webu (linkovi u daljnjem tekstu)
  • Pisana riječ u obliku knjige - Spring Persistence with Hiberante  (http://www.amazon.com/Spring-Persistence-Hibernate-Beginning-Tepper/dp/1430226323)
Napisani redoslijed nije slučajan, smatram da je to najbolji način za naučiti. Službenu dokumentaciju obavezno pročitajte ali nemojte previše ni pokušavati shvatiti iz nje. Je, super je napisana i sve to stoji ali pokušavati sve to zapamtiti - ne vidim smisla. Zato pročitajte dokumentaciju, neki važniji pojmovi će vam ostati u glavi, što je i najvažnije i pređite na tutorijale. Nema smisla raditi tutorijale dok ne prođete dokumentaciju jer neće znati o čemu se radi. A nakon što prođete tutorijale vratite se još jednom na dokumentaciju i sve će vam sjesti na mjesto - vjerujte me.
I dolazimo do knjige. (moj veliki uzdah - brz pretjerivanja!) Cijenim trud autora, ali nikako ni pod koji slučajem nemojte pokušati naučiti ovu temu preko ove knjige tj. nemojte napraviti istu pogrešku kao ja. U životu nisam našao knjigu koja ima više bugova. Skidanjem zipa sa službene stranice knjige i pokušavanje pokretanja builda na istim projektom je urodilo plodom od 63 errora?!? Čovjek bi pomislio da ako nešto prodaješ da ćeš i stajati iza toga. Istina za volju, nisu oni krivi. Kad su tiskali knjigu url od mavenovog repozitorija je bio drugačiji, ali tko se može sjetiti da to provjeri godinu dana kasnije? Malo traženja po googlu mi je dalo riješenje, ali to je samo vrh sante errora u knjizi.
Premda knjiga nije za početnika i nakon što se se uhvatili u koštac sa temom nemojte raditi primjere iz knjige. Knjigu uzmite kao lagano štivo gdje ćete vidjeti neke principe kako se nešto radi. Što se toga tiče knjiga ima neprocjenjivo znanje za prenijeti čitaocu.

I dolazimo do tutorijala, ruku na srce, od njih ćete najviše naučiti. Dati ću 2 linka na 2 turorijala a na vama je da odlučite koji vam se više sviđa. Napominjem da postoje još tutorijala na web, ali ja vam predlažem one koje sam ja prošao i što je važnije - znam da rade. Pošto svaki nudi čitatelju oduzimanje života na jedno minimalno sat vremena, ako ne i više, nema smisla raditi nešto što neće raditi ili što vas uči krivo.
Pa da dam i linkove:
  1. http://viralpatel.net/blogs/2010/11/spring3-mvc-hibernate-maven-tutorial-eclipse-example.html
  2. http://krams915.blogspot.com/2011/01/spring-mvc-3-hibernate-annotations.html
Nisu isti ali uče istu stvar na 2 načina. Redoslijed ostavljam vama, ali pojasnit ću što vam svako donosi/odnosi. Oba tutorijala se zasnivaju na MySQL bazi podataka, ali možete odabrati bilo koju.

Virapatel - ovo je ujedno i moj prvi tutotorial na koji sam naišao da radi. Što nije mala stvar. Treba imati na umu da je ovaj tutorial odrađen pomoću Mavena. Ovaj tutorial bi nazvao "lakšim" tj. napraviti ćete CRD dijelova od CRUD aplikacije. Naime u primjeru nije napravljen dio za editiranje zapisa. Druga stvar koja ga čini "lakšim" je da je kod rascijepkan u više klasa i na prvi pogleda samim time lakši za čitanje. Ali u drugom primjeru ćete vidjeti da je ovo duži način i da se sve može odraditi u manje linija koda. Glavni nedostatak je što nema komentara u kodu.
Skinite primjer, pokušajte pratiti i prepisati kod i pokušajte shvatiti kako cijela stvar radi. I zatim pređite na drugi tutorial.

Krams - koliko je ovaj tutorial dobar govori činjenica da Spring framework daje ovaj tutorial na svojim službenim stranicama kao tutorial za naučiti integraciju hiberante i springa. Još jedna stvar koja mu ide u prilog je da je nakon uočenih pogrešaka u kodu, autor je isti popravio na webu ali i u kodu te ponovni zip projekta stavio na web. Mogli bi se ugledati na njega momci koji pišu knjige na istu temu :)
Sad da kažem zašto je ovaj tutorial dobar: dobro objašnjen, hrpa komentara tako da kad gledate kod jasno vam je šta je šta. Ovaj tutorijal nudi i editiranje zapisa, tako da imate sve dijelove CRUD aplikacije.
Kada su nabrojane prednosti dolaze ne red nedostatci: nema ih! Dobro uvijek se može naći nešto, pa ako moram birati onda ću kao nedostatak navesti upotrebu loggera. S jedne strane je super jer daje priliku pregledavanja logova na serveru, a da s druge strane je to nedostatak jer uz sve silne komentare dodavanje loggera i komentara za njih kod je prenatrpan. Kad sam prolazio kod, brisao sam logger i komentare da vidim samo kod. Ali to sam ja.

Naravno jedna stvar na koju treba imati na umu je da oba primjera koriste MySQL bazu podataka, tako da ako hoćete koristiti neku drugu potrebno je napraviti promjene u jdbc.properties datoteki za Virapatel, te spring.properties datoteci za Krams. Ne zaboravite napraviti baze u MySQL-u pod imenima koja su navedena u tim properties datotekama, te ne zaboravite unjeti svoj username i password  za root  vašeg MySQL. Ako vam primjeri koje skinete ne budu radili onda niste napravili ove korake koje sam zadnje opisao.
S time svime na umu, sretno! Mislim da ću uskoro i ja dati neki praktičniji primjer ovoj temi, a do tada prođite ova dva tutotorijala i dokumentaciju.

subota, 21. siječnja 2012.

Lista Hibernate anotacija

Nešto sinoć surfam bespućima internetskih valova i kad mi na um nešto padne. Ne nije knjiga s police, nego ideja. Bacim se u pretragu, te potvrdim ono što sam i mislio. Na netu ne postoji (barem ja nisam mogao naći) listu hibernate anotacija. Samo onako prosta lista gdje s jedne strane su anotacija, a s druge kratko objašnjenje anotacije. Čak, što me i začudilo, ne postoji ništa slično ni na RefCardz?!? Najbliže što se tome može naći je na jbossovoj dokumentaciji o hiberanteu u ovom formatu:
http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/

Ali to nije ono što ja želim. Samo kada vidim scrollbar koliko je mršav u gornjem desnom uglu - muka mi je. To definitivno nije ono što ja želim i trebam. Meni treba lista anotacija (bez primjera primjenjivanja istih) kada nešto radim da bacim pogled u nadi da mi dođe inspiracija kako nešto napraviti.
Pogledao sam i knjigu Hibernate Recepies, A Problem-Solution-Approach koju imam. Ni tamo ne postoji ništa takvo, možda sam i naivan što sam išao i gledati kad naslov kaže kakva je knjiga i s kojim pristupom obrađuju teme. Ali da ne bude - nismo znali. Pa evo da i ja dodam koji centimetar znanja u metre valova u bespuću interneta.
Napominjem da neću stavljati anotacije za Hibernate Search i ako uspijem za Cashing. To su područja koja su nauke same za sebe i mogli bi se pisati blogovi, knjige i sl. samo za njih. Pa da počnem:

  • @Entity - osnovna antacija kojom označavamo klasu koju želimo mapiratu u bazu
  • @Id - uz entity minimum potreban za mapiranje klase. Označava primarni ključ
  • @GeneratedValue - automatska inkrementacija id-a
  • @Table - služi za definiranje imena tablice, kataloga i scheme za vašu klasu
  • @Version - dodavanje "verzije" u dodatnu kolonu radi uspoređivanja kontaktirajućih updateva 
  • @Transient - po defaultu sva polja u klasi će biti mapirana u bazi, ako neko polje ne želimo mapirati koristimo ovu anotaciju
  •  @Lob - po defaultu npr. za String Hibernate će pretvoriti to u bazi u VarChar s dužinom od 255 znakova, tako da je Lob oznaka za tkz. velike oznake. 
  • @Embeddable - umetanje i spajanje komponenti u klasu
  • @OneToOne - mapiranje jedan naprama jedan
  • @OneToMany - mapiranje jedna naprema više
  • @ManyToMany - mapiranje više naprema više
  • @JoinColumns - na kojoj osnovi će se vršiti mapiranje
  • @PrimaryKeyColumn i @PrimaryKeyColumns - definiraju primarni ključ subklasa
  • @SecondaryTable - mapiranje klase u nekoliko tablica
  • @Cashable - oznaka da ćemo koristiti cashing u entitiju
  • @NamedQuery i @NamedQueries - stvaranje upita (ne znam kako da to prevedem na Hr) - stvaranje named queries
  • @NotNull - ne dopuštanje null vrijednosti
  • @Size.max - definiranje veličine polja
  • @Min, @Max - definiranje raspona
Naravno ovo nisu sve anotacije, niti se trudim ih sve napisati. Neke je jednostavno bez primjera ili poviše rečenica nije lako opisati. Npr. ne znam kako da prevedem named query osim imenovanog upita?!? Ujedino sam i dobio ideju za neki budući post - izgubljeni u prijevodu, koliko se "prevođenjem" programerskih izraza gubi u prijevodu. Za sada toliko, s vremenom proširit ću ovaj popis.

četvrtak, 12. siječnja 2012.

Hibernate - up and running

Vrijeme je da posvetim malo pažnje Hibernatu. Inače smatram da treba dignuti spomenik osobi koja je došla uopće na ideju da napravi ORM. Mislim da osoba koja je pokušala se povezati na bazu u bilo kojem jeziku jednom kad upozna ORM, se ne vraća se nazad. Odnosno kao što sam ja rekao Once you go ORM, you never go back :)

JDBC je super stvar, ali u usporedbi sa bilo kojim ORM-om (MyBatis, Hibernate...), JDBC gubi i to za puno. Samo kada se upoređuje gdje sve kod klasičnog povezivanja putem JDBC-a gdje se sve može dogoditi exception - sve bi trebalo biti jasno. Kod otvaranja veze, kod konfirmacije usernamea i passworda, kod izvršavanja SQL naredbe, zatvaranja veze....

U ovom postu ću objasniti što je sve potrebno (znači min. konfiguracija) da bi se koristio Hibernate. Prvo što se treba napraviti je otići na http://www.hibernate.org/downloads.html i skinuti verziju Hibernate koja nam treba. Ako se koristi Maven, onda je ovaj korak nepotreban jer nam ne trebaju jar-ovi nego samo dodamo zavisnosti u pom.xm. U ovom primjeru ću koristiti jarove a ne maven zavisnosti. Još treba naglasiti da ću koristiti verziju 3.6 Hibernate.

Kad je zip skinut i odzipan, naravite novi projekt u Eclipsu. Znači obični Java Project (ništa više) jer ćemo napraviti program koji rezultat prikazuje u konzoli. Nakon što je napravljen novi projekt, desni klik na folder projekta i pod Build Pathom dodamo jarove koji su nam potrebni. Jednostavno dodate sve jarove koji se nalaze u odpakiranom hibernate zip folder pod folderom lib/required. Što je i logično :) još dadajte i jar koji se nalaze u folderu lib/jpa. Još jedan jar se ne smije zaboraviti, a to je jar od JDBC drivera baze podataka koju ćemo koristiti u projektu. Ja ću koristiti MySql bazu pa mi zato treba i pripadajući driver koji se može naći ovdje:
http://www.mysql.com/products/connector/

Hibernateu stvarno ne predstavlja nikakav problem koji ćete bazu podataka koristiti. Možete koristiti MySQL, PostgreSQL, Derby DB... samo dodate u build path pripadajući jdbc driver i to je to, sve ostalo je isto za sve.

Pa da krenemo. Da bi program mogao raditi uz pomoć Hiberatea, potrebne su 3 stvari:
  1. Potrebno je kreirati bazu na serveru koju ćemo koristiti. Hibernate može stvarati tablice, ali ne može stvoriti bazu
  2. Potrebno je u projektu definirati hiberante.cfg.xml što je zapravo konfiguracijski xml gdje definiramo koji su korisnički podatci za bazu (korisničko ime i password), koje ćemo klase definirati kao tablice u bazi i još neke postavke
  3. i zadnje ali ni pod kojim slučajem ne najmanje važno postaviti Entity i Id  anotacije u klasi koju ćemo koristiti.
Naravno postoji još neke stvari koje trebamo napraviti u main klasi, ali o tome kad dođemo do toga.
Napravim novu klasu pod imenom Automobil. Ono što je velika koristi i prednost Hibernatea je da on koristi POJO klase.

@Entity
@Table(name="VOZILA")
public class Contact {
   
    @Id
    private int id;
     private String ime;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getIme() {
        return ime;
    }
    public void setIme(String ime) {
        this.ime = ime;
    }
}
  
Kao što je vidljivo ovo je obična POJO klasa sa geterima i seterima. Uz dodatak anotacija.
Ono na što treba točnije trebalo bi se raditi je paziti kod importa. Kaže se da je good practice (pogotovo kod ovih POJO klasa) importe raditi iz javax persistenca, a ne iz hiberantea. Importi iz hiberantea se rade za query, session factory i ostalo što je specifično za Hibernate, dok velika većina anotacija koje se stavljaju u POJO klase su postale dio standarda tj. javax persistenca. Naravno ništa vašem programu neće faliti ako napravite importe iz hibernatea, ali razlog zašto bi ih trebalo raditi iz javax persistenca jer su oni dio standarda i ako nam se pokaže potreba da npr. prebacimo se na neki drugi orm, moramo promijeniti samo importe u main klasi, dok POJO klase ostaje kakve jesu. A sada da objasnim anotacije i što su one zapravo.

Kada je hiberante kao ORM izašao na svjetlo dana nisu postojale anotacije nego se koristilo xml mapiranje. Znači za svaku klasu se radio zasebni xml u kojem su se pisali properties. Uglavnom isto kao anotacije samo uz puno više pisanja nepotrebnog koda. Anotacije su utoliko bolje jer su brže za napraviti, a da ne pričam da se nalaze u klasi koju nam treba. Ne trebamo otvarati xml file mapiranja i uspoređivati xml s klasom. Pomoću anotacija govorimo Hiberanteu šta mi točno želimo od klase i podataka koji se nalaze u njim.
Tako npr. jedna od glavnih anotacija je @Entity jer pomoću nje govorimo Hibernateu da ta klase je klasa koju on treba pretvoriti u tablicu i onda on može odraditi taj posao za nas. Sljedeća anotacija koja je potrebna da bi stvar radila je @Id anotacija. Ona jednostavno govori orm-u koje polje će biti primarni ključ u tablici, jer kao što svi znamo svaka tablica mora imati primarni ključ. I to je to što se anotacija tiče. Naravno postoji cijeli niz anotacija koje možemo uključiti i koje ćemo koristiti ako radimo išta ozbiljnije od običnog Hello world primjera, ali za sada toliko. U nekom sljedećem postu ću obraditi samo anotacije.

Nakon što smo odredili koje će klase orm koristiti potrebni je podesiti postavke, a one se rade u hiberante.cfg.xml file. Jednostavno ne pišete cijeli kod napamet ili iz početka odite u odzipani folder koji ste skinuli i pretražite za datoteke cfg.xml i iskoristite već postojani xml kao predložak. Dobro provjerite rezultate pretrage jer postoje cfg xml-ovi koji nisu potpuni.

A sada da objasnim par stvari:
Pod <!-- Database connection settings --> naravno unosite podatke koje se odnose na vezu, te tu unesite podatke koje odgovaraju vašim potrebama. Malo zbunjujući pojam je tag dialact. To nije ništa drugo nego sintaksa koju ćete koristiti u pisanju vašeg koda koji se bavi upitima. Postoji čitav niz dijalekata, ali ako koristite MySQL odaberite MySQL dialekt. Ta opcija postoji ako želite koristiti dialekt koji se koristi isključivo u određenoj bazi podataka a npr. nije definiran u standardnoj SQL sintaksi  i na to je jedini način na koji možete koristiti taj dialek.
<property name="hbm2ddl.auto">create</property> je vrlo važan tag! I jedna vrlo moćna funkcija ORM-a. Ovo zapravo govori Hiberanteu da kada pokrenete program ako on ne nađe tablicu da je stvori, a ako postoji već on je dropa i ponovo stvori sa novim podatcima. A ako stavimo vrijednost umjesto create na update, onda pri pokretanju (ako postoji već tablica sa istim imenom) on je neće dropati pa ponovo kreirati nego će samo zapisati novonastale promjene. Tako da se kaže da u development fazi se ovo postavi na create a kad se isporučuje program onda se ova vrijednost postavi na update.
Još nam je jedno svojstvo ostalo za podesiti, a to je sljedeće:
<mapping class="com.punoimepaketa.ImeKlase"/> Ovdje jednostavno stavimo puno ime paketa i klase koju želimo da Hiberante pretvori u tablicu, tj. sve one klase u kojima smo stavili @Entity anotaciju. Naime nije dovoljno staviti anotaciju, jer ako ovaj korak ne odradimo neće se dogoditi ništa.


Još nam samo preostaje da napravimo našu main klasu i to je to. Pošto je ovaj post namijenjen više kao teorijski a ne kao praktični primjer, tj. post koji će vam skrenuti pažnju na neke stvari koju su potrebne, neću sada ovdje pisati main klasu. Ujednimo imam osjećaj da pišem preduge postove i da će se teško naći osoba koja će ih cijele pročitati. Još jedna činjenica je da nitko neće doći na moj blog naučiti Hibernate, naime ovo sve može poslužiti kao dobar podsjetnik ili kao dobra smjernica.
Zato ću u jednom u sljedećih postova napraviti praktični primjer gdje ću u detalje objasniti main klasu i gdje ću dati cijeli kod. Do tada pozdrav