You are on page 1of 32

Introduction to Java Hibernate

Developing enterprise applications involves a lot of efforts to store the business objects in the database. Usually,70% of the efforts to develop enterprise applications are writing the code to maintain database connections and save the entities to database. Most of the enterprise applications are developed using bject riented techni!ues. "he business logic inside the application flows in the form of objects instead of te#tual messages as it used to be in the days of structural programming where we had set of variable to perform operations or indicate the state of an entity. "oday, bject riented technologies are used to solve the comple# problems and maintain the business flow. nly saving the objects to the database is a stage where the objects are transformed bac$ to te#t and stored to the database. "o understand this problem,consider the following code snippets.

"his is typically how the connection is obtained in %ava language.

Class.forName(driverClass); java.sql.Connection connection = java.sql.DriverManager.getConnection(databaseUrl,databaseUser,databas ePass ord);

&uppose we have an object of User class,and we need to store this object to the database. 'onsider the following function(

!rivate void saveUser(User "ser) t#ro s $%&'(ce!tion ) Pre!ared$tatement !stmt = connection.!re!are$tatement(*insert into "sers val"es(+,+,+)*); !stmt.set,nt(-,"ser.get,d()); !stmt.set$tring(.,"ser.getName()); !stmt.set$tring(/,"ser.get'mail()); !stmt.set$tring(0,"ser.get1ddress()); !stmt.e(ec"te(); 2

"he problem with this code is that this is scattered everywhere in the application which affects the maintainability of the application. "here are many problems with this approach li$e(

'ode is scattered at different un)manageable places. *f your design changes after developing the application,it will be too e#pensive to identify the places where changes are re!uired. Difficult to identify and fi# the bugs Managing the database connections is a difficult tas$ since the &+, code is scattered,so are the database connections. Managing the transactions is a comple# tas$.

Due to these problems,bug fi#ing is an accepted stage of an application development process which ma$es the application too e#pensive even after the successful completion of development cycle.

*t is highly needed to have a mechanism to isolate the database persistent code and write it so efficiently that when there is a change in the database design,it can be easily implemented with the belief that there is no un)identified place which may show a bug later.

Benefits of Relational Database Systems:

searching and sorting is fast -or$ with large amounts of data -or$ with groups of data %oining, aggregating &haring across multiple users and multiple locations 'oncurrency ."ransactions/ &upport for multiple applications 'onsistent *ntegrity 'onstraints at different levels "ransaction isolation

Issues with Relational Database systems:

Database Modeling does not support polymorphism 0usiness logic in the application server could be duplicated in the database as stored procedures Does not ma$e use of real world objects

1#tra code re!uired to map the %ava objects to database objects. 2ibernate is an open source object3relational mapping tool for %ava that lets you develop persistent classes and persistent logic without caring how to handle the data. 2ibernate not only ta$es care of the mapping from %ava classes to database tables .and from %ava data types to &+, data types/,but also provides data !uery and retrieval facilities and can significantly reduce development time otherwise spent with manual data handling in &+, and %D0'. 2ibernate4s goal is to relieve the developer from 56% of common data persistence related programming tas$s. 2ibernate ma$es it far easier to build robust,high)performance database applications with %ava. 7ou only need to write a simple 8 % .8lain ld %ava bject/,create an 9M, mapping file that describes relationship between the database and the class attributes and call few 2ibernate :8*s to load3store the persistent objects.

*n object oriented systems,we represent entities as objects and classes and use database to persist those objects. Most of the data)driven applications today,are written using object oriented technologies. "he idea of representing entities as set of classes is to re)use the classes and objects once written.

"o understand the scenario,consider a web application that collects users personal information and stores them to the database. :lso there could be a page that displays all the saved users. -hen implementing this $ind of solution, we may store the data by getting the re!uest parameters and simply

putting it into &+, insert statements. &imilarly when displaying,we can select the desired record from the database,and display them on dynamic web page by iterating through the result set. 0ut wait...does it sound good to have persistent related code scattered everywhere on the web page; -hat if we need to modify the design of our database after we have developed few pages; r even if we want to replace our low)cost development database with an enterprise)class production database that have entirely different &+, synta#; Do we need to change the &+, !ueries everywhere in our code;

"o overcome this problem,we may want to develop %ava0eans representing the entities in the database. -e can develop a 8ersistence Manager that can operate on the given %ava0ean and perform several persistent operations li$e fetch,store,update,search etc. so that we don4t need to write persistence related code in our core area of application. :dvantage of using this techni!ue is that we can pass on this simple %ava0ean to any of the different layers of the application li$e a web layer,an 1%0 layer or any other layer we may have in our application.

-e have isolated our persistence related code so that whenever there is a change in the design,or we change the database environment we can change our persistence code. r we can have several copies of the 8ersistence Manager to wor$ with different databases so that based on some configuration parameter,we can choose the right 8ersistence Manager instance. 0ut this is still very difficult as we might ignore some database specific settings while writing so many 8ersistence Managers for different applications.

2ere the concept of bject <elational mapping comes. 0y bject <elational mapping . 3< mapping/ we mean the one)to)one mapping of class attributes with the columns of a database entity. Mapping includes the name of the attribute versus database field,the data type,and relation with other entities or classes. &o if we write a framewor$ that can ta$e the object to relation mapping and provide persistence facilities on the given %ava0eans,we can use it for different applications and different databases. &o,if anyone want to configure the application on a database that was not $nown at the time of writing the framewor$,he can simply write a mapping file and the application will start wor$ing on that environment.

"han$s to the open source community= we don4t need to write such framewor$s anymore. -e have 2ibernate which allows bject3<elation mapping and provides persistence to the abject with the help of simple :8*s where we can specify the operations and the operands .%ava0eans/. JDBC %ava Database 'onnectivity .%D0'/ is a set of :8*s to connect to the database in a standard way. &ince 2ibernate provides bject3<elation mapping,it must communicate to the database of your choice. :nd that cannot happen without the use of a vendor dependent component that understands the target database and the underlying protocol. Usually the database vendors provide set of 4connectors4 to

connect with their database from e#ternal applications with different set of technologies 3 languages. %D0' driver is widely accepted connector that provides a fairly standard implementation of the %D0' specification. "he point of discussion of %D0' here is,that you should $now the basics of %D0' and how to use it with 2ibernate.

Database connection can be provided by the 2ibernate framewor$ or by a %>D* Data source. A third method,user-provided JDBC connections,is also available,but it's rarely used. Typically,in standalone applications,we confi ure the JDBC connection properties in hibernte.cf .!ml file. "n case of applications deployed in an application server,we may choose to use a container-mana ed data source,or provide a selfmana ed connection that we mi ht already be usin throu hout the application. #ibernate itself does not impose a restriction to open or confi ure a separate connection for the #ibernate use only and $eep other confi urations to be used by rest of the application.

Before startin off with the #ibernate,ma$e sure that you have essential set of JDBC libraries for the database you are oin to use for your application. The Hibernate Alternative :s discussed above,2ibernate provides data storage and retrieval by direct mapping of bject and <elation without letting the application developer worry about the persistence logic. "here are few alternatives to 2ibernate.

7ou may choose to use plain &+, !ueries to store and retrieve data but that is not an alternate to 2ibernate as using plain &+, !ueries does not provide ma#imum of the features provided by 2ibernate. 7ou can use 1nterprise %ava 0eans. *n particular,1ntity 0eans are good alternate to 2ibernate. 0ut again,you need to see if you really have the re!uirements of an 1%0 container; 7ou can use the spring framewor$ .www.springframewor$.org/ to implement a D: layer which would centrali?e as well as minimi?e any future need to change persistence implementations. "here are many other bject3<elation mapping products available li$e %0 . b%ect<elational0ridge/,"or!ue,'astor,'ayenne,"%D etc. @or more details see http(33java) source.net3open)source3persistence Hibernate Architecture and A I 2ibernate is written in %ava and is highly configurable through two types of configuration files. "he

first type of configuration file is named #ibernate.cfg.(ml. n startup,2ibernate consults this 9M, file for its operating properties,such as database connection string and password,database dialect,and mapping files locations. 2ibernate searches for this file on the classpath. "he second type of configuration file is a mapping description file .file e#tension 3.#bm/ that instructs 2ibernate how to map data between a specific %ava class and one or more database tables. >ormally in a single application,you would have one hibernate.cfg.#ml file,and multiple .hbm files depending upon the business entities you would li$e to persist.

2ibernate may be used by any %ava application that re!uires moving data between %ava application objects and database tables. "hus,it4s very useful in developing two and three)tier %A11 applications. *ntegration of 2ibernate into your application involves(

*nstalling the 2ibernate core and support %:< libraries into your project 'reating a 2ibernate.cfg.#ml file to describe how to access your database &electing appropriate &+, Dialect for the database. 'reating individual mapping descriptor files for each persistable %ava classes

2ere are some commonly used classes of 2ibernate.

!"#"! Session$actory %org.hibernate.SessionFactory&

&ession@actory is a thread safe .immutable/ cache of compiled mappings for a single database. Usually an application has a single &ession@actory. "hreads servicing client re!uests obtain &essions from the factory. "he behavior of a &ession@actory is controlled by properties supplied at configuration time.

!"#"' Session %org.hibernate.Session&

: session is a connected object representing a conversation between the application and the database. *t wraps a %D0' connection and can be used to maintain the transactions. *t also holds a cache of persistent objects,used when navigating the objects or loo$ing up objects by identifier.

!"#"( Transaction %org.hibernate.Transaction&

"ransactions are used to denote an atomic unit of wor$ that can be committed .saved/ or rolled bac$ together. : transaction can be started by calling session.begin4ransaction() which actually uses the transaction mechanism of underlying %D0' connection,%": or ' <0:.: &ession might span several "ransactions in some cases.

: complete list of 2ibernate :8*s can be found at http(33www.hibernate.org3hibBdocs3vC3api3. Re)istration Case Study "o demonstrate the different steps involved in a 2ibernate application,-e will develop a console based application that can add,update,delete or search a user in the database. :s discussed previously,we can use racle or My&+, database for storing the user information.

%e&ll use a sin le table 'users& to store the user information with the followin fields(

Column *ame

Data Ty+e

Constraints

U&1<B*D

>UM01<

8<*M:<7 D17

@*<&"B>:M1

"19"

> >1

,:&"B>:M1

"19"

> >1

:E1

>UM01<

> >1

1M:*,

"19"

> >1

'reate this table in the database. "he synta# for the oracle is given below.

'<1:"1 U&1<B*D

":0,1 >UM01< @*<&"B>:M1 ,:&"B>:M1 :E1 1M:*,

8<*M:<7

U&1<&. D17, F:<'2:<.A0/, F:<'2:<.A0/, >UM01<, F:<'2:<.G0/

/H

*f you are using My&+, database,you can create the table using following synta#.

'<1:"1 U&1<B*D

":0,1 >UM1<*' @*<&"B>:M1 ,:&"B>:M1 :E1 1M:*,

8<*M:<7

U&1<&. D17, '2:<.A0/, '2:<.A0/, >UM1<*', '2:<.G0/

/H Creatin) the Hibernate Confi)uration >ow it is the time to create our 2ibernate configuration file. "his file will contain the hibernate session configuration li$e the database driver,user name and password or a %>D* data source if you would li$e to use one,cache provider ad other session parameters. :lso this file contains the entries for bject to

<elation mapping that we will create later. *nitially let4s create the file with minimum re!uired information and understand what does that information mean.

'reate a new file #ibernate.cfg.(ml in src folder and add the following contents to this file.

I;#ml versionJ4K.04 encodingJ4utf)L4;M I=D '"781 hibernate)configuration 8U0,*' N)332ibernate32ibernate 'onfiguration D"D C.0331>N Nhttp(33hibernate.sourceforge.net3hibernate)configuration)C.0.dtdNM Ihibernate)configurationM Isession)factoryM Iproperty nameJNconnection.urlNM jdbc(oracle(thin(Olocalhost(K6AK(91 I3propertyM Iproperty nameJNconnection.driverBclassNM oracle.jdbc.driver. racleDriver I3propertyM Iproperty nameJNconnection.usernameNM &7&"1M I3propertyM Iproperty nameJNconnection.passwordNM manager I3propertyM I=)) &et :uto'ommit to true ))M Iproperty nameJNconnection.autocommitNM true I3propertyM I=)) &+, Dialect to use. Dialects are database specific ))M Iproperty nameJNdialectNM org.hibernate.dialect. racleDialect I3propertyM I=)) Mapping files ))M Imapping resourceJNcom3visualbuilder3hibernate3User.hbm.#mlN 3M I3session)factoryM I3hibernate)configurationM

:s you can see,the session factory configuration is set of few properties re!uired for a database connection. connection"url is the %D0' U<, re!uired to connect to the database. connection"driver,class is the %D0' Driver class which we normally use in 'lass.for>ame while establishing a connection to the database. connection"username and connection"+assword are the database user name and password respectively. connection"autocommit sets the :utocommit property of the underlying connection. -e have set it to true so that we don4t need to commit the transactions

ourselves unless we want to do it intentionally.

"his configuration is for an racle database at my machine. *f you are unaware of how to build a U<, for an racle database,note that the you need to replace 91 with an appropriate &*D of your racle database,localhost with the *8 address of the machine where racle is running if not on local machine,and K6AK with the port. *n most cases,you will only change the &*D and rest of the parameters will remain the same.

*f you are using My&+,,you should put the appropriate U<,,Driver class name,user name,password and the Dialect name. "he Dialect for My&+, is org.#ibernate.dialect.M5$%&Dialect. Driver class for the My&+, is com.m5sql.jdbc.Driver and the U<, for My&+, is jdbc(mys!l(33IserverM(IportM3Idatabase)nameM. "he default port for My&+, is CC0P.

"he ne#t important step is to add the %D0' driver jar file to the project libraries just li$e we added the struts libraries. @or oracle,it is ojdbcKG.?ip or ojdbcKG.jar and can be found under racle installation3jdbc3lib. @or e#ample,if racle 91 is installed in '(Qoracle#e,the ojdbcKG.jar can be found on the following path. '(Qoracle#eQappQoracleQproductQK0.A.0QserverQjdbcQlib. 7ou can also download it from http(33www.min!.se3products3dbvis3drivers.html freely.7ou can download the My&+, %D0' driver freely from http(33dev.mys!l.com3downloads3connector3j36.0.htmll -ritin) the first Java $ile )et&s start with our first *ava class. +emember we have a table ,users- in the database. )et&s write a simple bean that represents this table.

+ac.a)e com.visualbuilder.hibernateH 3RR R /author Fisual0uilder R R3 +ublic class User S +rivate lon) user*d J 0 H +rivate &tring first>ame J NNH +rivate &tring last>ame J NNH +rivate int age J 0H +rivate &tring email J NNH

+ublic int get:ge./ S return ageH T +ublic void set:ge.int age/ S this.age J ageH T +ublic &tring get1mail./ S return emailH T +ublic void set1mail.&tring email/ S this.email J emailH T +ublic &tring get@irst>ame./ S return first>ameH T +ublic void set@irst>ame.&tring first>ame/ S this.first>ame J first>ameH T +ublic &tring get,ast>ame./ S return last>ameH T +ublic void set,ast>ame.&tring last>ame/ S this.last>ame J last>ameH T +ublic lon) getUser*d./ S return user*dH T +ublic void setUser*d.lon) user*d/ S this.user*d J user*dH T T -ritin) the ma++in) file Mapping files are the heart of 3< mapping tools. "hese are the files that contain field to field mapping between the class attributes and the database columns. ,et4s write a mapping file for the User class that we want to persist to the database.

I;0ml versionJNK.0N;M I=D '"781 hibernate)mapping 8U0,*' N)332ibernate32ibernate Mapping D"D C.0331>N Nhttp(33hibernate.sourceforge.net3hibernate)mapping)C.0.dtdN M Ihibernate1ma++in)M Iclass nameJNcom.visualbuilder.hibernate.UserN tableJNU&1<&N M

Iid nameJNuser*dN typeJNjava.lang.,ongN columnJNuserBidN M I)enerator classJNincrementN 3M I3idM I+ro+erty nameJNfirst>ameN typeJNjava.lang.&tringN columnJNfirstBnameN lengthJNA0N 3M I+ro+erty nameJNlast>ameN typeJNjava.lang.&tringN columnJNlastBnameN lengthJNA0N 3M I+ro+erty nameJNageN typeJNjava.lang.*ntegerN columnJNageN lengthJN)KN 3M I+ro+erty nameJNemailN typeJNjava.lang.&tringN columnJNemailN lengthJNG0N 3M I3classM I3hibernate1ma++in)M

:s you can see,we have mapped all of the attributes of the class NUserN to the columns of the table we created previously. >ote the NidN attribute which maps the "ser,d field of class User is defined in a different way than the other properties. "he id tag is used to indicate that this is a primary $ey,and a 6generator7 tag is used to generate the primary $ey using different techni!ues. -e have used the increment class,but there are also available different classes to support different $ind of $ey generation techni!ues li$e generating $ey from a se!uence,selecting from database etc. -e can also use a custom $ey generator class.

,et us now add the mapping file to the 2ibernate configuration file hibernate.cfg.#ml. :fter adding the mapping resource entry,the hibernate.cfg.#ml loo$s li$e this.

I;0ml versionJ4K.04 encodingJ4utf)L4;M I=D '"781 hibernate)configuration 8U0,*' N)332ibernate32ibernate 'onfiguration D"D C.0331>N Nhttp(33hibernate.sourceforge.net3hibernate) configuration)C.0.dtdNM Ihibernate1confi)urationM Isession1factoryM I+ro+erty nameJNconnection.urlNMjdbc(oracle(thin(Olocalhost(K6AK(91I3+ro+ertyM I+ro+erty nameJNconnection.driverBclassNMoracle.jdbc.driver. racleDriverI3+ro+ertyM I+ro+erty nameJNconnection.usernameNM&7&"1MI3+ro+ertyM I+ro+erty nameJNconnection.passwordNMmanagerI3+ro+ertyM

I=)) &et :uto'ommit to true ))M I+ro+erty nameJNconnection.autocommitNMtrueI3+ro+ertyM I=)) &+, Dialect to use. Dialects are database specific ))M I+ro+erty nameJNdialectNMnet.sf.hibernate.dialect. racleDialectI3+ro+ertyM

I=)) Mapping files ))M Ima++in) resourceJNcom3visualbuilder3hibernate3User.hbm.#mlN 3M I3session1factoryM I3hibernate1confi)urationM -ritin) the Business Com+onent &o far,we have written a User class that we want to persist and a mapping file that describes the relationship of each of the attributes of the class to the database columns. -e have also configured the 2ibernate &ession@actory .hibernate.cfg.#ml/ to use the User.hbm.#ml. >ow it is the time to write a business component that can perform different operations on the User object.

2"! Session

0efore writing the business component,we need to understand a hibernate 4session4. :s discussed in section K.6,a hibernate session is an instance of org.#ibernate.$essiono!en$ession() of $ession8actor5. 1very database operation begins and ends with a $ession. @or e#ample,we can begin4ransaction(),save(),"!date() or delete() an object with the help of a $ession. and is obtained by calling

ur business component will use the &ession to perform its business operations.

package com.vis"alb"ilder.#ibernate.client; import org.#ibernate.$ession; import com.vis"alb"ilder.#ibernate.User; 933 3 UserManager 3 @author :is"al;"ilder 39 public class UserManager ) private $ession session = n"ll; public UserManager($ession session) ) if(session == n"ll) throw new <"ntime'(ce!tion(*,nvalid session object. Cannot instantiate t#e UserManager*); this.session = session; 2 public void saveUser(User "ser) ) session.save("ser); 2 public void "!dateUser(User "ser) ) session."!date("ser); 2 public void deleteUser(User "ser) ) session.delete("ser); 2 2

-ritin) the Test Client


,et us write a test client that utili?es the different methods of the UserManager we have just introduced. -e will obtain the $ession8actor5 and open a session and then call different methods of the UserManager to see if they wor$ or not.

package com.vis"alb"ilder.#ibernate.client; import org.#ibernate.3; import org.#ibernate.cfg.Config"ration; import com.vis"alb"ilder.#ibernate.3; public class 4estClient ) 93 3 4#is met#od b"ilds a defa"lt "ser to c#ec= if t#e >iernate config"ration is or=ing or not 39 public User b"ildUser() ) User "ser = new User(); "ser.set8irstName(*?o#n*); "ser.set&astName(*'lison*); "ser.set1ge(.-); "ser.set'mail(*jo#n@vis"alb"ilder.com*); return "ser; 2 93 3 4#is met#od gets t#e defa"lt $ession8actor5 config"red in #ibernate.cfg.(ml and o!ens a session 39 public $ession o!en$ession() ) $ession8actor5 session8actor5 = new Config"ration().config"re().b"ild$ession8actor5(); $ession session =session8actor5.o!en$ession(); return session; 2

public User test$aveUser(UserManager manager) ) User "ser = b"ildUser(); manager.saveUser("ser); $5stem.o"t.!rintln(*User saved it# ,D = * "ser.getUser,d()); return "ser; 2

public void testU!dateUser(UserManager manager,User "ser) ) "ser.set8irstName(*1ndre *); manager."!dateUser("ser); $5stem.o"t.!rintln(*User "!dated it# ,D = * "ser.getUser,d()); 2

public void testDeleteUser(UserManager manager,User "ser) ) manager.deleteUser("ser); $5stem.o"t.!rintln(*User deleted it# ,D = * "ser.getUser,d()); 2 public static void main($tringAB args) ) 4estClient client = new 4estClient(); $ession session = client.o!en$ession(); UserManager manager = new UserManager(session);

User "ser = client.test$aveUser(manager);

client.testU!dateUser(manager,"ser);

client.testDeleteUser(manager,"ser); session.fl"s#(); 2 2 3ana)in) Associations :ssociation is a relationship of one class to another class $nown as 4relationships4 in database terminology. Usually the database design involves the master detail tables to represent the relationship of one entity to another. &truts provides a mechanism to manage one)to)many and many)to)many relationships. 0efore moving forward,let4s create the necessary database tables to show associations.

,et4s create a table !#oneCn"mbers to represent phone numbers of a user. @ollowing script can be used to create the table in racle.

C<'14' 41;&' P>DN'CNUM;'<$ ( U$'<C,D NUM;'< <'8'<'NC'$ U$'<$(U$'<C,D), NUM;'<C4EP' :1<C>1<(FG), P>DN' NUM;'<, P<,M1<E H'E(U$'<C,D,NUM;'<C4EP') );

4#e same table can be created in My&+, using the script given below.

C<'14' 41;&' P>DN'CNUM;'<$ ( U$'<C,D NUM'<,C ND4 NU&& <'8'<'NC'$ U$'<$(U$'<C,D), NUM;'<C4EP' C>1<(FG) ND4 NU&&, P>DN' NUM'<,C, P<,M1<E H'E(U$'<C,D,NUM;'<C4EP') );

Ie #ave t o tables in t#e databaseJ U$'<$ and t#e P>DN'CNUM;'<$ it# one to man5 relations#i! s"c# t#at one User man5 contain G or more !#one n"mbers. Create a class P#oneN"mber and create its ma!!ing file follo ing t#e ste!s to create User class. 4#e code for t#e P#oneN"mber class is s#o n belo .

package com.vis"alb"ilder.#ibernate; import java.io.$erialiKable; 933 3 P#oneN"mber 3 @author :is"al;"ilder 39 public class P#oneN"mber implements $erialiKable ) private long "ser,d = G; private $tring n"mber45!e = *#ome*; private long !#one = G; public $tring getN"mber45!e() ) return n"mber45!e; 2 public void setN"mber45!e($tring n"mber45!e) ) this.n"mber45!e = n"mber45!e; 2 public long getP#one() ) return !#one; 2 public void setP#one(long !#one) ) this.!#one = !#one; 2

public long getUser,d() ) return "ser,d; 2 public void setUser,d(long "ser,d) ) this."ser,d = "ser,d; 2 2

>ote that we have made the 8hone>umber class &eriali?eable. "his is because we need a composite $ey in this class,and 2ibernate re!uires tat the class that represents the composite $ey must be &eriali?eable. "he mapping file 48hone>umber.hbm.#ml4 contains following te#t.

I;0ml versionJNK.0N;M I=D '"781 hibernate)mapping 8U0,*' N)332ibernate32ibernate Mapping D"D C.0331>N Nhttp(33hibernate.sourceforge.net3hibernate)mapping)C.0.dtdN M Ihibernate1ma++in)M Iclass nameJNcom.visualbuilder.hibernate.8hone>umberN tableJN82 >1B>UM01<&N M Icom+osite1idM I.ey1+ro+erty columnJNU&1<B*DN nameJNuser*dN typeJNjava.lang.,ongN 3M I.ey1+ro+erty columnJN>UM01<B"781N nameJNnumber"ypeN typeJNjava.lang.&tringN3M I3com+osite1idM I+ro+erty nameJNphoneN typeJNjava.lang.,ongNM Icolumn nameJN82 >1N precisionJNAAN scaleJN0N 3M I3+ro+ertyM I3classM I3hibernate1ma++in)M

:dd the mapping resource for 8hone>umber in hibernate.cfg.#ml file. "o do this,locate the line Ima++in) resourceJNcom3visualbuilder3hibernate3User.hbm.#mlN 3M in the hibernate.cfg.#ml file and add the following line just after this line.

Ima++in) resourceJNcom3visualbuilder3hibernate38hone>umber.hbm.#mlN 3M -e want to write few lines of code so that when we select a user,we automatically get all the phone numbers associated with this user. "o do this,add a method 4get8hone>umbers4 that returns a list of users in class User and 4set8hone>umbers4 that ta$es a ,ist as argument. "he complete listing of class User after adding these two methods is shown below.

package com.vis"alb"ilder.#ibernate; 933 3 @author :is"al;"ilder 3 39 public class User ) private long "ser,d = G; private $tring firstName = **; private $tring lastName = **; private int age = G; private $tring email = **; private java."til.$et !#oneN"mbers = new java."til.>as#$et(); public int get1ge() ) return age; 2 public void set1ge(int age) ) this.age = age; 2 public $tring get'mail() ) return email; 2

public void set'mail($tring email) ) this.email = email; 2 public $tring get8irstName() ) return firstName; 2 public void set8irstName($tring firstName) ) this.firstName = firstName; 2 public $tring get&astName() ) return lastName; 2 public void set&astName($tring lastName) ) this.lastName = lastName; 2 public long getUser,d() ) return "ser,d; 2 public void setUser,d(long "ser,d) ) this."ser,d = "ser,d; 2 public java."til.$et getP#oneN"mbers() ) return !#oneN"mbers; 2 public void setP#oneN"mbers(java."til.$et !#oneN"mbers) ) if(!#oneN"mbers L= n"ll) this.!#oneN"mbers = !#oneN"mbers;

2 2

"he phone>umbers 2ash"able will be used to store all phone numbers associated with this User. "he new changes are highlighted in gray. -e have added the methods for getting and setting the phone umbers,we need to add the mapping for the phone numbers now. :dd the following bloc$ in User.hbm.#ml before the I3classM tag.

6set name=*!#oneN"mbers* cascade=*all*7 6key col"mn=*U$'<C,D*97 6one-to-many class=*com.vis"alb"ilder.#ibernate.P#oneN"mber* 97 69set7

:s you can see,the tags are very simple. "he cascade attribute of set tells the 2ibernate how to deal with the child records when a parent is deleted or a child is added.

>ow it is the time to test our functionality. <emember the "est'lient class where we had few bloc$s of code e#plaining the save,update and delete functionality. @or the time being,comment the call to testDeleteUser and replace the contents of method testU!dateUser with the following code.

8hone>umber ph J new 8hone>umber./H ph.setUser*d.user.getUser*d.//H ph.set>umber"ype.N fficeN/H ph.set8hone.5CG767/H user.get8hone>umbers./.add.ph/H ph J new 8hone>umber./H ph.setUser*d.user.getUser*d.//H ph.set>umber"ype.N2omeN/H ph.set8hone.5CG767/H user.get8hone>umbers./.add.ph/H manager.saveUser.user/H

&ystem.out.println.NUser updated with *D J N user.getUser*d.//H

-e are adding two phone numbers to the recently saved user objects. >ote that we even don4t need to save the 8hone>umber. "hese are automatically saved as we add them to the User. +uery the database and see how these instances are persisted. nce you see the values in the database,re)enable the code to delete the User object and see what happens with the child 8hone>umber objects.

&o far,we have dealt with one to many association,we can configure the 2ibernate for one to one and many to many associations. @or more details on how to ma$e 2ibernate configuration for other $ind of associations,see http(33www.hibernate.org3hibBdocs3vC3reference3en3htmlBsingle3Ututorial)associations $indin) by +rimary .ey *n the previous section,we tested the basic functionality of our hibernate application. -ith few lines of code,we were able to perform the basic operations li$e insert,update and delete on the database table,and add few children without writing a single &+, !uery. *n enterprise applications,an efficient search mechanism is highly needed. 2ibernate provides a set of different techni!ues to search a persisted object. ,et us see a simple mechanism to find an bject by primary $ey without using a !uery.

:dd the following method in UserManager class.

public User getUser(long "ser,d) ) User "ser = (User)session.get(User.class, new &ong("ser,d)); return "ser; 2

"his is the whole logic of finding a user by primary $ey. ,et4s test this code by adding the following method in "est'lient.

public void test8ind;5P=(UserManager manager) ) User "ser = manager.getUser(-);998ind t#e "ser if("ser == n"ll) ) $5stem.o"t.!rintln(*No "ser fo"nd 2else ) $5stem.o"t.!rintln(*User fo"nd it# ,D=* "ser.getUser,d() *Mn* it# ,D=-*); it# id=-

*MtName=* "ser.get&astName() *Mn* *Mt'mail=* "ser.get'mail() **); java."til.,terator n"mbers = "ser.getP#oneN"mbers().iterator(); while(n"mbers.#asNe(t()) ) P#oneN"mber !# = (P#oneN"mber)n"mbers.ne(t(); $5stem.o"t.!rintln(*MtMtN"mber 45!eJ* !#.getN"mber45!e() *Mn* *MtMtP#one N"mberJ* !#.getP#one()); 2 2 2

:dd the call to this method in main. "o do this,add the following line in main. client.test8ind;5P=(manager);

<eplace the user id K by some reasonable user id that e#ists in the database and there are few phone numbers added against that user id. 7ou will see the following output.

User fo"nd Name='lison

it# ,D=-

'mail=jo#n@vis"alb"ilder.com N"mber 45!eJDffice P#one N"mberJN/0OFO N"mber 45!eJ>ome P#one N"mberJN/0OFO Hibernate 4uery 5an)ua)e %H45& *n the previous section,we tried to find a persisted user by user id which was primary $ey in that case. -hat if we want to search a user by user name,age or email and none of these attributes is a primary $ey. 2ibernate provides a !uery language similar to the standard &+, to perform operations on the 2ibernate objects. "he advantage of using 2+, instead of standard &+, is that &+, varies as different databases are adopted to implement different solutions,but 2+, remain the same as long as you are within the domain of 2ibernateH no matter which database you are using. ,et us learn to embed 2+, in our e#ample to find the users with age greater than C0. 0efore doing this,ma$e sure that you have some of the users over the age of C0. @or e#ample,i issued the following !uery on my racle console to update the age of few users.

update users set ageJCK where userBid in.6,L,5,KK,KC,KG/H

Modify this !uery to include some of the records in your users table.

,et4s write the logic to find the users in our business component. :dd the following method in UserManager.

public java."til.&ist getUsers;51ge(int min1age) ) org.#ibernate.%"er5 q = session.create%"er5(*from User " #ere ".age 7= Jmin1ge*); q.set,nteger(*min1ge*, min1age); return q.list(); 2

>ote that the !uery uses NUserN which is the object name and not the table name which is NUsersN. &imilarly the Nu.ageN is an attribute of the User object and not the column name of the table. &o whatever the name of the table may be,and whatever the presentation of that table or columns at the database level may be,we will use the same standard synta# while communicating with the hibernate.

:lso note the parameter Nmin:geN. "he parameters in an 2+, !uery are represented with N(N.colon/ character and can be bound using the inde# or the parameter name in org.hibernate.+uery.

,et4s write a piece of ode to test this functionality. :dd the following method in "est'lient.

public void test8ind;51ge(UserManager manager) ) java."til.,terator "sers = manager.getUsers;51ge(/G).iterator(); while("sers.#asNe(t()) ) User "ser = (User)"sers.ne(t(); $5stem.o"t.!rintln(*User fo"nd it# ,D=* "ser.getUser,d() *Mn* *MtName=* "ser.get&astName() *Mn* *Mt'mail=* "ser.get'mail() **); java."til.,terator n"mbers = "ser.getP#oneN"mbers().iterator(); while(n"mbers.#asNe(t()) ) P#oneN"mber !#one = (P#oneN"mber)n"mbers.ne(t(); $5stem.o"t.!rintln(*MtMtN"mber 45!eJ* !#one.getN"mber45!e() *Mn* *MtMtP#one N"mberJ* !#one.getP#one()); 2 2 2

:dd the call to this method in main. "o do this,add the following line in main. client.test8ind;51ge(manager);

<un the program and see that all the users we modified above are displayed with respective phone numbers.

@ollowing points should be $ept in mind when wor$ing with 2+,.

+ueries are case insensitive,e#cept the %ava class and attribute names. 2ence &1,1'" and select are the same,but User and user are not.

*f the class or pac$age does not find a place in imports,then the objects have to be called with the pac$age name. @or e#ample,if com.visualbuilder.hibernate.User is not imported,then the !uery would be Nfrom com.visualbuilder.hibernate.UserN and so on.

@or more details on 2+,,visit http(33www.hibernate.org3hibBdocs3vC3reference3en3html3!ueryh!l.html 6sin) native S45 *n previous section,we learnt to use the 2ibernate +uery ,anguage .2+,/ that focused on the business entities instead of the vendor dependent synta#. "his does not mean that we are bound to use the 2+, throughout the 2ibernate application if we want to perform some database operations. 7ou may e#press a !uery in &+,,using create$%&%"er5() and let 2ibernate ta$e care of the mapping from result sets to objects. >ote that you may at any time call session.connection() and use the %D0' Connection directly. *f you chose to use the 2ibernate :8*,you must enclose &+, aliases in braces.

,et4s see how to use the &+, !ueries by adding the functionality to find a user by user id using native &+, in our UserManager. :dd the following method in UserManager class.

+ublic User getUser0y*d.lon) user*d/ S org.hibernate.&+,+uery !uery J session.create&+,+uery.NN N&1,1'" u.userBid as Su.user*dT,u.firstBname as Su.first>ameT,u.lastBname as Su.last>ameT,u.age as Su.ageT,u.email as Su.emailT N N@< M U&1<& SuT -21<1 SuT.userBidJN user*d NN/H !uery.add1ntity.NuN,User.class/H java.util.,ist l J !uery.list./H java.util.*terator users J l.iterator./H User user J nullH if.users.has>e#t.// user J .User/users.ne#t./H return userH T

*n the above code,the result type is registered using q"er5.add'ntit5(*"*,User.class) so that 2ibernate $nows how to translate the <esult&et obtained by e#ecuting the !uery. :lso note that the aliases in the !uery are placed in braces and use the same prefi# NuN as registered in !uery.add1ntity..../. "his way 2ibernate $nows how to set attributes of the generated object. :lso this way we can eliminate the confusion of attributes when more than one tables are used in !uery and both of them contain the same column name. q"er5.list() actually e#ecutes the !uery and returns the <esul&et in the form of list of objects. -e $new that this !uery is going to return only one object,so we

returned only the first object if available.

,et4s test this code by adding the following method in the "est'lient.

public void test8ind;5Native$%&(UserManager manager) ) User "ser = manager.getUser;5,d(.); $5stem.o"t.!rintln(*User fo"nd "sing native sql "ser.getUser,d() *Mn* *MtName=* "ser.get&astName() *Mn* *Mt'mail=* "ser.get'mail() **); java."til.,terator n"mbers = "ser.getP#oneN"mbers().iterator(); while(n"mbers.#asNe(t()) ) P#oneN"mber !#one = (P#oneN"mber)n"mbers.ne(t(); $5stem.o"t.!rintln(*MtMtN"mber 45!eJ* !#one.getN"mber45!e() *Mn* *MtMtP#one N"mberJ* !#one.getP#one()); 2 2 it# ,D=*

:dd the call to this method in main. "o do this,add the following line in main. client.test8ind;5Native$%&(manager);

0e sure to pass a valid user id to this method that e#ists in the database with few valid phone numbers. "his code will result in the following output.

User fo"nd "sing native sql

it# ,D=.

Name='lison 'mail=jo#n@vis"alb"ilder.com N"mber 45!eJDffice P#one N"mberJN/0OFO N"mber 45!eJ>ome P#one N"mberJN/0OFO

@or more details on using native &+, in 2ibernate,see 2ibernate documentation. 6sin) Criteria 4ueries &o far we have seen how to use 2+, and native &+, to perform certain database operations. -e saw that the 2+, was much simpler than the native &+, as we had to provide database columns and the mapping attributes along with mapping classes too to get fully translated java objects in native &+,. 2ibernate provides much simpler :8* called 'riteria +ueries if our intention is only to filter the objects or narrow down the search. *n 'riteria +ueries,we don4t need to provide the select or from clause. *nstead,we just need to provide the filtering criteria. @or e#ample name li$e 4%a4,or id in .K,A,C/ etc. ,i$e 2+,,the 'riteria :8* wor$s on java objects instead on database entities as in case of native &+,.

,et4s write a method in UserManager to filter the users that have user id within a set of passed user id4s.

public java."til.&ist getUser;5Criteria(&ongAB items) ) org.#ibernate.Criteria criteria = session.createCriteria(User.class); criteria.add(org.#ibernate.criterion.<estrictions.in(*"ser,d*, items)); return criteria.list(); 2

"his method returns the users and associated phone numbers that have one of the user id in items passed as an argument. &ee how a certain filter criteria is entered using <estrictions class. &imilarly we can use <estrictions.li=e,<estrictions.bet een,<estrictions.isNotN"ll,<estrict ions.isN"ll and other methods available in <estrictions class.

,et4s write the test code to verify that the filter we provided using 'riteria wor$s. :dd the following method in "est'lient.

public void test8ind;5Criteria(UserManager manager) ) java."til.,terator "sers = manager.getUser;5Criteria(new &ongAB)new &ong(-),new &ong(.)2).iterator(); while("sers.#asNe(t()) ) User "ser = (User)"sers.ne(t(); $5stem.o"t.!rintln(*User fo"nd it# ,D=*P"ser.getUser,d()P*Mn* P

*MtName=*P"ser.get&astName()P*Mn* P *Mt'mail=*P"ser.get'mail() P **); java."til.,terator n"mbers = "ser.getP#oneN"mbers().iterator(); while(n"mbers.#asNe(t()) ) P#oneN"mber !#one = (P#oneN"mber)n"mbers.ne(t(); $5stem.o"t.!rintln(*MtMtN"mber 45!eJ*P!#one.getN"mber45!e()P*Mn* P *MtMtP#one N"mberJ*P!#one.getP#one()); 2 2 2

:dd the call to this method in main. "o do this,add the following line in main. client.test@ind0y'riteria.manager/H

-e passed the two user ids to the function. &o we should get the two users .if we have in the database with these user id4s/ with appropriate phone number entries if they e#ist in the database. 2ere is what gets displayed under my environment. 7ou should adjust the appropriate user id4s to get the results.

User fo"nd Name='lison

it# ,D=-

'mail=jo#n@vis"alb"ilder.com N"mber 45!eJDffice P#one N"mberJN/0OFO N"mber 45!eJ>ome P#one N"mberJN/0OFO User fo"nd Name='lison 'mail=jo#n@vis"alb"ilder.com N"mber 45!eJ>ome P#one N"mberJN/0OFO N"mber 45!eJDffice P#one N"mberJN/0OFO 6sin) Ant to run the +ro7ect *n previous sections,we have learnt the widely used components of 2ibernate. ur development environment was eclipse and a set of 2ibernate libraries. Usually ant is used to build and run the 2ibernate applications. *n this section,we will configure our project to use ant and build without any help of eclipse even from command line. it# ,D=.

"o start with ant(

Download and install the latest available version :pache :nt from http(33ant.apache.org &et environment variable %:F:B2 M1 to point to the available %DD location li$e d(QjavaQjAsd$K.G.AB0G

&et environment variable :>"B2 M1 to point to the ant installation directory li$e d(QjavaQapache)ant)K.P.A

:dd %:>"B2 M1%Qbin to your 8:"2 environment variable so that the ant binaries are accessible.

ur ant installation is ready. ,et4s configure our project to use ant.

'reate a directory lib at the root of our project and place the libraries re!uired by our project in this folder. "he libraries include all the 2ibernate jar files we added in eclipse project libraries and the %D0' driver. &ee the directory structure below to find where to place the libraries.

'reate an #ml file at the root of the project. i.e. where the src and lib residesH and add the following te#t in this file.

6+xml version=*-.G*+7 6project name=*#ibernateQt"torial* defa"lt=*r"n* basedir=*.*7 6LQQ set global !ro!erties for t#is b"ild QQ7 6property name=*srcdir* val"e=*src*97 6property name=*jardir* val"e=*jars*97 6property name=*b"ilddir* val"e=*b"ild*97 6property name=*libdir* val"e=*lib*97 6property name=*!ac=age* val"e=*com9vis"alb"ilder9#ibernate*97 6path id=*c!*7 6fileset dir=*R)libdir2*7 6include name=*3.jar*97 6include name=*#ibernate93.jar*97 6include name=*#ibernate9lib93.jar*97 69fileset7 69path7 6target name=*init*7 6mkdir dir=*R )b"ilddir2*97 6mkdir dir=*R)jardir2*97 69target7 6target name=*clean*7 6delete q"iet=*tr"e* dir=*R)b"ilddir2*97 6delete q"iet=*tr"e* dir=*R)jardir2*97 69target7 6target name=*com!ile* de!ends=*init*7 6javac srcdir=*R)srcdir2* destdir=*R)b"ilddir2* class!at#ref=*c!*7 6include name=*R

)!ac=age293.java*97 6include name=*R)!ac=age29client93.java*97 69javac7 69target7 6target name=*jar* de!ends=*com!ile*7 6jar destfile=*R)jardir29a!!.jar*7 6fileset dir=*R)b"ilddir2*7 6include name=*R)!ac=age293393.class*97 69fileset7 6fileset dir=*R)srcdir2*7 6include name=*R )!ac=age293.#bm.(ml*97 6include name=*3.cfg.(ml*97 69fileset7 69jar7 69target7 6target name=*r"n* de!ends=*jar*7 6java classname=*com.vis"alb"ilder.#ibernate.client.4estClient* class!at#ref=*c!*7 6classpath7 6pathelement location=*R )jardir29a!!.jar* 97 69classpath7 69java7 69target7 69project7 "his is the main build script that can be used to automatically build the source,copy the configuration files.R.hbm.#ml and R.cfg.#ml/,build the jar file and e#ecute the program. pen the command prompt,change your current directory to the project root,and issue the following command( ant "he out put of this command is shown below(

'JMecli!se!rojectsM#ibernateQt"torial7ant ;"ildfileJ b"ild.(ml initJ Am=dirB Created dirJ 'JMecli!se!rojectsM#ibernateQt"torialMb"ild Am=dirB Created dirJ 'JMecli!se!rojectsM#ibernateQt"torialMjars com!ileJ AjavacB Com!iling 0 so"rce files to 'JMecli!se!rojectsM#ibernateQt"torialMb"ild jarJ AjarB ;"ilding jarJ 'JMecli!se!rojectsM#ibernateQt"torialMjarsMa!!.jar r"nJ AjavaB log0jJI1<N No a!!enders co"ld be fo"nd for logger (org.#ibernate.cfg.'nvironment). AjavaB log0jJI1<N Please initialiKe t#e log0j s5stem !ro!erl5. AjavaB User fo"nd it# ,D=-0 AjavaB Name='lison AjavaB 'mail=jo#n@vis"alb"ilder.com AjavaB N"mber 45!eJ>ome AjavaB P#one N"mberJN/0OFO AjavaB N"mber 45!eJDffice AjavaB P#one N"mberJN/0OFO AjavaB User fo"nd it# ,D=-O AjavaB Name='lison AjavaB 'mail=jo#n@vis"alb"ilder.com AjavaB N"mber 45!eJ>ome AjavaB P#one N"mberJN/0OFO AjavaB N"mber 45!eJDffice AjavaB P#one N"mberJN/0OFO ;U,&D $UCC'$$8U&

&o,you can see that the ant did a magic for us by doing all the configuration,including the necessary libraries and automatically e#ecuting the client program for us.

You might also like