č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

1 komentar:

  1. Pozdrav. Gde si ti danas kada je ovo pisano pre 6 godina :). Ja sam sada tu gde si ti odprilike bio kada si ovo pisao. Citam sve sto si pisao za Spring i mogu ti samo reci da mi je krivo sto si prestao sa ovim objasnjavanjima. Ovo je daleko prakticnije od dokumentacija. U svakom slucaju hvala i na ovih nekoliko postova sto imas.

    OdgovoriIzbriši