Vous êtes sur la page 1sur 35

Hibernate

1. Advantage of Hibernate over JDBC


2. Hibernate Setup with an web Application
3. First Hibernate Application
4. Hibernate mapping with Database TABLE
5. Hibernate Data Type-Java Data Type - SQL Data Type mapping
6. One to Many Relation in Hibernate
7. One to Many Relation in Hibernate bi-directional
8. Many to Many Relation in Hibernate
9. HQL: The Hibernate Query Language
10. Criteria Queries
11. Criteria Queries : Equal (eq), Not Equal(ne), Less than (le), greater than (gt),greater
than or equal(ge) and Ordering the results
12. Criteria Queries: And OR conditions
13. Hibernate generator to generate id (primary key)
14. prevent concurrent update in Hibernate,slate object updatation in Hibernate,version
checking in Hibernate

Advantage of Hibernate over JDBC

Advantage are
1) Hibernate is data base independent, same code will work for all data bases like
ORACLE,MySQL ,SQLServer etc.
In case of JDBC query must be data base specific.

2) As Hibernate is set of Objects , you don't need to learn SQL language.


You can treat TABLE as a Object .
In case of JDBC you need to learn SQL.

3) Don't need Query tuning in case of Hibernate. If you use Criteria Quires in Hibernate then
hibernate automatically tuned your query and return best result with performance.
In case of JDBC you need to tune your queries.

4) You will get benefit of Cache. Hibernate support two level of cache. First level and 2nd level.
So you can store your data into Cache for better performance.
In case of JDBC you need to implement your java cache

5) Hibernate supports Query cache and It will provide the statistics about your query and database
status.
JDBC Not provides any statistics.

6) Development fast in case of Hibernate because you don't need to write queries.

7) No need to create any connection pool in case of Hibernate. You can use c3p0.
In case of JDBC you need to write your own connection pool.

8) In the xml file you can see all the relations between tables in case of Hibernate. Easy readability.

9) You can load your objects on start up using lazy=false in case of Hibernate.
JDBC Don't have such support.
10 ) Hibernate Supports automatic versioning of rows but JDBC No

Hibernate Setup with an web Application

Follow the steps to setup Hibernate.

Step 1. Create folders like below.

testApp    
     |    
----src     // Java Source Code folder
              |    
-------------beans //Source Code folder   
                 |    
----------------Offer.java //Source Code    
-------------servlet //Source Code folder   
                 |    
----------------DBStartUpServlet.java //Source Code    
-------------dao //Source Code folder   
                 |    
----------------HibernateUtil.java //Source Code    
----config     // config folder where all the configuration files present
              |    
-------------hibernate.cfg.xml //Hibernate Config file   
-------------Offer.hbm.xml// hibernate mapping with Offer TABLE    
-------------log4j.properties// log4j setting    
----WEB-INF //within folder    
          |    
---------web.xml //file   
---------classes //folder   
---------lib //within folder   
              |    
-------------hibernate3.jar //jar file   
-------------antlr-2.7.6rc1.jar //jar file   
-------------asm.jar //jar file   
-------------asm-attrs.jar //jar file   
-------------c3p0-0.9.0.jar //jar file for connection pool   
-------------classes12.jar //if you use ORACLE DATABASE jar file   
-------------mysql-connector-java-5.0.4-bin.jar //if you use MySQL DATABASE jar file   
-------------commons-logging.jar //jar file   
-------------commons-validator.jar //jar file   
-------------dom4j-1.6.1.jar //jar file   
-------------jta.jar //jar file   
-------------log4j-1.2.11.jar //jar file   
-------------nls_charset12.jar //jar file   

Step 2. Add DBStartUpServlet Entry into the web.xml file

This servlet is only for load configuration files related to Hibernate and create Session Factory
on start up .
Create Session Factory is very Expensive
Create Session Factory is very Expensive so we added one servlet to create on server startup
Initialize Connection pool on startup
Initialize Connection pool on startup using c3p0.
Initialize log4j configuration
Initialize log4j configuration on startup.

<?xml version="1.0" encoding="ISO-8859-1"?>


<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>Hibernate</display-name>
<description>
Hibernate Setup </description>
<servlet>
<servlet-name>
DBStartUpServlet
</servlet-name>
<servlet-class>
servlet.DBStartUpServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
</web-app>
Step 3. DBStartUpServlet Code

package servlet;
public class DBStartUpServlet extends HttpServlet {
/** Initialising the Logger */
protected static final Logger
logger=Logger.getLogger(DBStartUpServlet.class);
public void init(ServletConfig config) throws
ServletException {
System.out.println("\n**** Initializing Hibernate Init
Servlet ********** \n");
super.init(config);

//This is for local properties.


String cfgDir = "D:\\testApp\\config";
logger.info("config dir:"+cfgDir);
initLogPro(cfgDir);
try{
HibernateUtil.appHome = cfgDir;
HibernateUtil.initMonitor();
}catch(Exception e){
e.printStackTrace();
}

/** Handles the requests from http client.


* @param request servlet request
* @param response servlet response
*/
protected void service(HttpServletRequest
request,HttpServletResponse response)
throws ServletException, java.io.IOException {
}

private void initLogPro(String path){


try{
PropertyConfigurator.configure(path+File.separatorChar+"lo
g4j.properties");
}catch(Exception ex){
System.out.println("Log4J can not be initialized");
logger.info("Log4J can not be initialized");

}
}

Step 4. HibernateUtil.java code


package dao;
public class HibernateUtil {
public static String appHome = "No";
private static SessionFactory sessionFactory;
private static final ThreadLocal threadSession = new
ThreadLocal();
private static final ThreadLocal threadTransaction = new
ThreadLocal();

// Create the initial SessionFactory from the default


configuration files
public static void configure(){
try {
String path_properties =
appHome+File.separatorChar+"hibernate.cfg.xml";
Configuration configuration = new Configuration();
configuration.addFile(path_properties);
sessionFactory
=configuration.configure().buildSessionFactory();

} catch (Throwable ex) {

throw new ExceptionInInitializerError(ex);


}
}
public static SessionFactory getSessionFactory() {
if(sessionFactory==null) configure();
return sessionFactory;
}

public static Session getSession(){


Session s = (Session) threadSession.get();
// logger.debug("session"+s);
if (s == null) {

s = getSessionFactory().openSession();
threadSession.set(s);
// logger.debug("session 1 $"+s);
}
return s;
}

Step 5. hibernate.cfg.xml for hibernate configuration (within config folder)

<?xml version='1.0' encoding='utf-8'?>


<lt;!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/techfaqdb</property>
<property name="connection.username">techfaq</property>
<property name="connection.password">techfaq</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="hibernate.c3p0.min_size">1</property>
<property name="hibernate.c3p0.max_size">4</property>
<property name="hibernate.c3p0.timeout">1800</property>
<property name="hibernate.c3p0.max_statements">50</property>
<!-- MySQL dialect//different for different Database -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property
name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<mapping resource="Offer.hbm.xml"/>
</session-factory>
</hibernate-configuration>

Step 6. Offer.java bean class.(within beans folder)

package beans;
public class Offer {
private long offerId;
private String offerName;
/**
* @return Returns the offerId.
*/ public long getOfferId() {
return offerId;
}
/**
* @param offerId The offerId to set.
*/
private void setOfferId(long offerId) {
this.offerId = offerId;
}
/** * @return Returns the offerName.
*/
public String getOfferName() {
return offerName;
}
/**
* @param offerName The offerName to set.
*/
public void setOfferName(String offerName) {
this.offerName = offerName;
}
}

Step 7. Offer.java and OFFER TABLE mapping in Offer.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="beans.Offer" table="OFFER">
<id name="offerId" column="offer_id" type="long">
<generator class="increment"/> // This generates the primary key
</id>
<property name="offerName" column="offer_name"/>
</class>
</hibernate-mapping>

Step 8. OFFER TABLE in your database

create table OFFER ( offer_id number; offer_name varchar );

Then start the server. Your SessionFactory is ready to serve.


You can call HibernateUtil.getSession() to get session object and do your coding

First Hibernate Application

This section describe a simple program to insert record into database and fetch the records
Follow the setps

Step 1. create a table name EMPLOYEE in your database

// for MySQL
create table EMPLOYEE (
id bigint(20) ,
name varchar
);
// FOR ORACLE
create table EMPLOYEE (
id number;
name varchar
);

Step 2. Create Emp.java bean class.


Hibernate uses the Plain Old Java Objects (POJOs) classes to map to the database table
(Emp.java to EMPLOYEE TABLE). We can configure the variables to map to the database
column.

public class Emp {


private long id;
private String name;
public long getId() {
return id;
}
private void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

Step 3. Emp.hbm.xml - This mapps EMPLOYEE TABLE and Emp.java

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Emp" table="EMPLOYEE">
<id name="id" column="id" type="long">
<generator class="increment"/> // This generates the primary key
</id>
<property name="name" column="name"/>
</class>
</hibernate-mapping>

Step 4. add Emp.hbm.xml into hibernate.cfg.xml

Hibernate provided connection pooling usning c3p0 and transaction management . Hibernate
uses the hibernate.cfg.xml to create the connection pool and setup required environment

<?xml version='1.0' encoding='utf-8'?>


<lt;!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/techfaqdb</property>
<property name="connection.username">techfaq</property>
<property name="connection.password">techfaq</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="hibernate.c3p0.min_size">1</property>
<property name="hibernate.c3p0.max_size">4</property>
<property name="hibernate.c3p0.timeout">1800</property>
<property name="hibernate.c3p0.max_statements">50</property>
<!-- MySQL dialect//different for different Database -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property
name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<mapping resource="Emp.hbm.xml"/>
</session-factory>
</hibernate-configuration>

Step 5. Here is the code for Save and Fetch data.

Hibernate Session is the main runtime interface for Hibernate which is used for DataBase
operataion. Session has the method like save () , update () , creteQuery() for Data Base operation.
You can get session using SessionFactory.openSession() method. SessionFactory allows
application to create the Hibernate Sesssion by reading the configuration from hibernate.cfg.xml
file. Then the save () method on session object is used to save the contact information to the
database.

public class TestExample {


public static void main(String[] args) {
Session session = null;
try{ // This step will read hibernate.cfg.xml
SessionFactory sessionFactory = new
Configuration().configure().buildSessionFactory();
session =sessionFactory.openSession();
System.out.println("Inserting Records");
Emp emp1 = new Emp();
emp1.setName("Nick");
session.save(emp1);
Emp emp2 = new Emp();
emp2.setName("Das");
session.save(emp2);
session.flush(); // insert data into databse
System.out.println("Save Done- finish database insert");
// Now fetch the Employee data
List empList = session.createQuery("from Emp").list();
//empList contains the list of Employee
for(int i=0;i
Emp emp = (Emp)empList.get(i);
System.out.println(emp.getName());
}
// Out put is : Nick Das
}catch(Exception e){
}finally{
session.close();
}
}
}

Hibernate mapping with Database TABLE

Follow the steps to mapp with Database TABLE.

Step 1. create a table name OFFER in your database

create table OFFER ( offer_id number; offer_name varchar );

Step 2. Create Offer.java bean class.

package beans;
public class Offer {
private long offerId;
private String offerName;
/**
* @return Returns the offerId.
*/ public long getOfferId() {
return offerId;
}
/**
* @param offerId The offerId to set.
*/
private void setOfferId(long offerId) {
this.offerId = offerId;
}
/** * @return Returns the offerName.
*/
public String getOfferName() {
return offerName;
}
/**
* @param offerName The offerName to set.
*/
public void setOfferName(String offerName) {
this.offerName = offerName;
}
}

Step 3. Offer.hbm.xml - This mapps OFFER TABLE and Offer.java

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="beans.Offer" table="OFFER">
<id name="offerId" column="offer_id" type="long">
<generator class="increment"/> // This generates the primary key
</id>
<property name="offerName" column="offer_name"/>
</class>
</hibernate-mapping>

Step 4. add Offer.hbm.xml into hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>


<lt;!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/techfaqdb</property>
<property name="connection.username">techfaq</property>
<property name="connection.password">techfaq</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="hibernate.c3p0.min_size">1</property>
<property name="hibernate.c3p0.max_size">4</property>
<property name="hibernate.c3p0.timeout">1800</property>
<property name="hibernate.c3p0.max_statements">50</property>
<!-- MySQL dialect//different for different Database -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property
name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<mapping resource="Offer.hbm.xml"/>
</session-factory>
</hibernate-configuration>

One to Many : Uni-Directional Relation in Hibernate

There are two table WRITER and STORY. One writer can write multiple stories. So the relation
is one-to-many uni-directional.

Step 1. create a table name WRITER and STORY in your database

create table WRITER (


ID number, //PRIMARY KEY
NAME varchar
);
create table STORY (
ID number,
INFO varchar,
PARENT_ID number // forign key - relate to ID Coulmn of WRITER.
);

Step 2. Mapping writer.hbm.xml- Which maps to WRITER TABLE.

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Writer" table="WRITER">
<id name="id" column="ID" type="int" unsaved-value="0">
<generator class="increment"/>
</id>
<list name="stories" cascade="all">
<key column="parent_id"/>
<one-to-many class="Story"/>
</list>
<property name="name" column="NAME" type="string"/>
</class>
</hibernate-mapping>

Step 3. Mapping story.hbm.xml- Which maps to STORY TABLE.

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Story" table="story">
<id name="id" column="ID" type="int" unsaved-value="0">
<generator class="increment"/>
</id>
<property name="info" column="INFO" type="string"/>
</class>
</hibernate-mapping>

Step 4. Create Writer.java bean class.

public class Writer {


private int id;
private String name;
private List stories;
public void setId(int i) {
id = i;
}
public int getId() {
return id;
}
public void setName(String n) {
name = n;
}
public String getName() {
return name;
}
public void setStories(List l) {
stories = l;
}
public List getStories() {
return stories;
}
}

Step 5. Create Story.java bean class.

public class Story {


private int id;
private String info;
public Story(){
}
public Story(String info) {
this.info = info;
}
public void setId(int i) {
id = i;
}
public int getId() {
return id;
}
public void setInfo(String n) {
info = n;
}
public String getInfo() {
return info;
}
}

Step 6. add writer.hbm.xml and story.hbm.xml into hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>


<lt;!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/techfaqdb</property>
<property name="connection.username">techfaq</property>
<property name="connection.password">techfaq</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="hibernate.c3p0.min_size">1</property>
<property name="hibernate.c3p0.max_size">4</property>
<property name="hibernate.c3p0.timeout">1800</property>
<property name="hibernate.c3p0.max_statements">50</property>
<!-- MySQL dialect//different for different Database -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property
name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<mapping resource="story.hbm.xml"/>
<mapping resource="writer.hbm.xml"/>
</session-factory>
</hibernate-configuration>

Here is the code : how to save

Save Example ..
Writer wr = new Writer();
wr.setName("Das");
ArrayList list = new ArrayList();
list.add(new Story("Story Name 1"));
list.add(new Story("Story Name 2"));
wr.setStories(list);
Transaction transaction = null;
try {
transaction = session.beginTransaction();
session.save(wr);
transaction.commit();
} catch (Exception e) {
if (transaction != null) {
transaction.rollback();
throw e;
}
} finally {
session.close();
}

One to Many Bi-Directional Relation in Hibernate

There are two table WRITER and STORY. One writer can write multiple stories. So the relation
is one-to-many . This tutorial describe the bi-directional relation. From WRITER object you can
get list of Stories and from story object you can get writer object.

Step 1. create a table name WRITER and STORY in your database

create table WRITER (


ID number, //PRIMARY KEY
NAME varchar
);
create table STORY (
ID number,
INFO varchar,
PARENT_ID number // forign key - relate to ID Coulmn of WRITER.
);

Step 2. Mapping writer.hbm.xml- Which maps to WRITER TABLE.

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Writer" table="WRITER">
<id name="id" column="ID" type="int" unsaved-value="0">
<generator class="increment"/>
</id>
<list name="stories" cascade="all">
<key column="parent_id"/>
<one-to-many class="Story"/>
</list>
<property name="name" column="NAME" type="string"/>
</class>
</hibernate-mapping>

Step 3. Mapping story.hbm.xml- Which maps to STORY TABLE.

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Story" table="story">
<id name="id" column="ID" type="int" unsaved-value="0">
<generator class="increment"/>
</id>
<property name="info" column="INFO" type="string"/>
<many-to-one name="writer" column="ID" lazy="false"/>
</class>
</hibernate-mapping>

Step 4. Create Writer.java bean class.

public class Writer {


private int id;
private String name;
private List stories;
public void setId(int i) {
id = i;
}
public int getId() {
return id;
}
public void setName(String n) {
name = n;
}
public String getName() {
return name;
}
public void setStories(List l) {
stories = l;
}
public List getStories() {
return stories;
}
}

Step 5. Create Story.java bean class.

public class Story {


private int id;
private String info;
private Writer writer; public Story(){
}
public Story(String info) {
this.info = info;
}
public void setId(int i) {
id = i;
}
public int getId() {
return id;
}
public void setInfo(String n) {
info = n;
}
public String getInfo() {
return info;
}
public void setWriter(Writer writer) {
this.writer = writer;
}
public Writer getWriter() {
return writer;
}
}
Step 6. add writer.hbm.xml and story.hbm.xml into hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>


<lt;!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/techfaqdb</property>
<property name="connection.username">techfaq</property>
<property name="connection.password">techfaq</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="hibernate.c3p0.min_size">1</property>
<property name="hibernate.c3p0.max_size">4</property>
<property name="hibernate.c3p0.timeout">1800</property>
<property name="hibernate.c3p0.max_statements">50</property>
<!-- MySQL dialect//different for different Database -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property
name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<mapping resource="story.hbm.xml"/>
<mapping resource="writer.hbm.xml"/>
</session-factory>
</hibernate-configuration>

Many to Many Relation in Hibernate

There are two table EVENTS and SPEAKERS . One Event can have multiple speakers. And One
Speaker can speak in multiple Event. So this is many to many relation. To maintain this relation
we have to introduce third TABLE name EVENT_SPEAKERS .

Step 1. create a tables EVENTS , SPEAKERS and EVENT_SPEAKERS in your database

create table EVENTS (


event_id number, //PRIMARY KEY
event_name varchar
);
create table SPEAKERS (
speaker_id number, //PRIMARY KEY
speaker_name varchar,
);
create table EVENT_SPEAKERS (
elt number,//primary key event_id number, speaker_id number
);

Step 2. event.hbm.xml - Hibenate mapping-Which maps to EVENTS TABLE

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Event" table="events">
<id name="id" column="event_id" type="long">
<generator class="increment"/>
</id>
<property name="name" column="event_name" type="string"
length="100"/>
<set name="speakers" table="event_speakers" cascade="all">
<key column="event_id"/>
<many-to-many class="Speaker"/>
</set>
</class>
</hibernate-mapping>

Step 3. Mapping speaker.hbm.xml- Which maps to SPEAKERS TABLE.

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Speaker" table="speakers">
<id name="id" column="speaker_id" type="long">
<generator class="increment"/>
</id>
<property name="name" column=" speaker_name" type="string"
length="100"/>
<set name="events" table="event_speakers" cascade="all">
<key column="speaker_id"/>
<many-to-many class="Event"/>
</set>
</class>
</hibernate-mapping>

Step 4. Create Event.java bean class.

public class Event{


private long id;
private String name;
private Set speakers;
public void setId(long id) {
this.id = id;
}
public long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setSpeakers(Set speakers) {
this.speakers = speakers;
}
public Set getSpeakers() {
return speakers;
}
}

Step 5. Create Speaker.java bean class.

public class Speaker{


private long id;
private String name;
private Set events;
public void setId(long id) {
this.id = id;
}
public long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set getEvents() {
return this.events;
}
public void setEvents(Set events) {
this.events = events;
}
}

Step 6. add event.hbm.xml and speaker.hbm.xml into hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>


<lt;!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/techfaqdb</property>
<property name="connection.username">techfaq</property>
<property name="connection.password">techfaq</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="hibernate.c3p0.min_size">1</property>
<property name="hibernate.c3p0.max_size">4</property>
<property name="hibernate.c3p0.timeout">1800</property>
<property name="hibernate.c3p0.max_statements">50</property>
<!-- MySQL dialect//different for different Database -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property
name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<mapping resource="event.hbm.xml"/>
<mapping resource="speaker.hbm.xml"/>
</session-factory>
</hibernate-configuration>

Here is the code : how to save and fetch data

Event event = new Event();


event.setName("Inverse test");
event.setSpeakers(new HashSet());
event.getSpeakers().add(new Speaker("Ram", event));
event.getSpeakers().add(new Speaker("Syam", event));
session.save(event); /// Save All the Data
event = (Event) session.load(Event.class, event.getId());
Set speakers = event.getSpeakers();
for (Iterator i = speakers.iterator(); i.hasNext();) {
Speaker speaker = (Speaker) i.next();
System.out.println(speaker.getFirstName());
System.out.println(speaker.getId());
}

HQL: The Hibernate Query Language The Hibernate Query Language is executed using
session.createQuery(). This tutorial includes from clause,Associations and joins, Aggregate
functions,The order by clause,The group by clause,Subqueries.

The from clause

from Employee // Employee is class name mapped to EMPLOYEE


TABLE
or
from Employee as e
or
from Employee e where e.empId = 3;
List empList = session.createQuery("from Employee").list();

Associations and joins

from Employee e where e.scopeModFlag = 1 and pc.isDeleted != 1


List empList = session.createQuery("from Employee e where
e.scopeModFlag = 1 and pc.isDeleted != 1").list();

Aggregate functions

select avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat)


from Cat cat ScrollableResults rs = session.createQuery("select
avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat) from Cat
cat").scroll();
if(rs.next()){
System.out.println(rs.get(0));
System.out.println(rs.get(1));
System.out.println(rs.get(2));
System.out.println(rs.get(3));
}
The order by clause

from Employee e order by e.name desc


List empList = session.createQuery("from Employee e order by e.name
desc").list();
asc or desc indicate ascending or descending order respectively.

The group by clause

select e.dept, sum(e.salary), count(e) Employee e group by cat.dept

Subqueries

from Employee as e
where e.name = some (
select name.nickName from Name as name
)

Criteria Queries The interface org.hibernate.Criteria represents a query against a particular


persistent class. The Session is a factory for Criteria instances.

Criteria : Select * from Employee.

Criteria criemp = session.createCriteria(Employee.class);


List emplist = criemp.list();

Restrictions to narrow result set

The class org.hibernate.criterion.Restrictions used to narrow result set.

// SELECT * FROM EMPLOYEE WHERE AGE=24; ----SQL


COMMAND
criteria query for above query is :
List empList =
session.createCriteria(Employee.class).add( Restrictions.eq("age", new
Integer(24) ) ).list();
// Not Equal in hibernate criteria // SELECT * FROM EMPLOYEE
WHERE AGE !=24; ----SQL COMMAND
criteria query for above query is :
List empList =
session.createCriteria(Employee.class).add( Restrictions.ne("age", new
Integer(24) ) ).list();

Ordering the results

// SELECT * FROM EMPLOYEE WHERE AGE=24 ORDER BY


EMP_NAME DESC; ----SQL COMMAND
criteria query for above query is :
List empList = session.createCriteria(Employee.class).
add( Restrictions.eq("age", new
Integer(24) ) ).addOrder( Order.desc("empname") ).list();

Associations

// SELECT e.name FROM EMPLOYEE e , address a where


e.address_id=a.address_id and a.country='US'; ----SQL COMMAND
criteria query for above query is :
List empList =
session.createCriteria(Employee.class).createAlias("address","add").
add( Restrictions.eq("add.country", "US" ) ).list();

Example queries

The class org.hibernate.criterion.Example allows you to construct a query criterion from a given
instance.

// SELECT * FROM EMPLOYEE e WHERE e.dept='IT'; ----SQL


COMMAND
criteria query for above query is :
Employee emp = new Employee();
cat.setDept('IT');
List emplist = session.createCriteria(Employee.class)
.add( Example.create(emp) )
.list();

Criteria Queries : Equal (eq), Not Equal(ne), Less than (lt), Less than or equal(le), greater
than (gt),greater than or equal(ge) and Ordering the results The interface
org.hibernate.Criteria represents a query against a particular persistent class. The Session is a
factory for Criteria instances. In this section it show how to create TABLE and POJO Java class
and Mapping with the Query.

Create TABLE EMPLOYEE.

Create TABLE EMPLOYEE(


id number;
name varchar;
age number;
);

Create Employee.java bean class.

Hibernate uses the Plain Old Java Objects (POJOs) classes to map to the database table
(Emp.java to EMPLOYEE TABLE). We can configure the variables to map to the database
column.

public class Employee {


private long id;
private String name;
private int age;
public long getId() {
return id;
}
private void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
private void setAge(int age) {
this.age = age;
}
}

Employee.hbm.xml - This mapps EMPLOYEE TABLE and Emp.java

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Employee" table="EMPLOYEE">
<id name="id" column="id" type="long">
<generator class="increment"/> // This generates the primary key
</id>
<property name="name" column="name"/>
<property name="age" column="age" type="int"/>
</class>
</hibernate-mapping>

Equal (eq)

Equal (eq) : Is used to check equal in the query.

// SELECT * FROM EMPLOYEE WHERE AGE=24; ----SQL


COMMAND
criteria query for above query is :
List empList =
session.createCriteria(Employee.class).add( Restrictions.eq("age", new
Integer(24) ) ).list();

NotEqual (ne)

NotEqual (ne) : Is used to check not equal in the query.

// SELECT * FROM EMPLOYEE WHERE AGE !=24; ----SQL


COMMAND
// Not Equal in hibernate criteria criteria query for above query is :
List empList =
session.createCriteria(Employee.class).add( Restrictions.ne("age", new
Integer(24) ) ).list();

Less than (lt)

Less than (lt) : Is used to check less than in the query.

// SELECT * FROM EMPLOYEE WHERE AGE < 24; ----SQL


COMMAND
// Not Equal in hibernate criteria criteria query for above query is :
List empList =
session.createCriteria(Employee.class).add( Restrictions.lt("age", new
Integer(24) ) ).list();
Less than or equal(le)

Less than or equal(le) : Is used to check less than or equal in the query.

// SELECT * FROM EMPLOYEE WHERE AGE <= 24; ----SQL


COMMAND
// Not Equal in hibernate criteria criteria query for above query is :
List empList =
session.createCriteria(Employee.class).add( Restrictions.le("age", new
Integer(24) ) ).list();

Greater than (gt)

Greater than (gt) : Is used to check greater than in the query.

// SELECT * FROM EMPLOYEE WHERE AGE > 24; ----SQL


COMMAND
// Not Equal in hibernate criteria criteria query for above query is :
List empList =
session.createCriteria(Employee.class).add( Restrictions.gt("age", new
Integer(24) ) ).list();

Greater than or equal (gt)

Greater than or equal (gt) : Is used to check greater than or equal in the query.

// SELECT * FROM EMPLOYEE WHERE AGE >= 24; ----SQL


COMMAND
// Not Equal in hibernate criteria criteria query for above query is :
List empList =
session.createCriteria(Employee.class).add( Restrictions.ge("age", new
Integer(24) ) ).list();

Ordering the results

// SELECT * FROM EMPLOYEE WHERE AGE=24 ORDER BY


NAME DESC; ----SQL COMMAND
criteria query for above query is :
List empList = session.createCriteria(Employee.class).
add( Restrictions.eq("age", new
Integer(24) ) ).addOrder( Order.desc("name") ).list();
Criteria Queries: And OR conditions The interface org.hibernate.Criteria represents a query
against a particular persistent class. The Session is a factory for Criteria instances. In this section
it show how to create TABLE and POJO Java class and Mapping with the Query.

Create TABLE EMPLOYEE.

Create TABLE EMPLOYEE(


id number;
name varchar;
age number;
);

Create Employee.java bean class.

Hibernate uses the Plain Old Java Objects (POJOs) classes to map to the database table
(Emp.java to EMPLOYEE TABLE). We can configure the variables to map to the database
column.

public class Employee {


private long id;
private String name;
private int age;
public long getId() {
return id;
}
private void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
private void setAge(int age) {
this.age = age;
}
}

Employee.hbm.xml - This mapps EMPLOYEE TABLE and Emp.java

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Employee" table="EMPLOYEE">
<id name="id" column="id" type="long">
<generator class="increment"/> // This generates the primary key
</id>
<property name="name" column="name"/>
<property name="age" column="age" type="int"/>
</class>
</hibernate-mapping>

And Condtion

This method returns the conjunctions of two expressions. Both conditions are 'true' then it
excutes the query otherwise not.

// SELECT * FROM EMPLOYEE WHERE AGE=24 AND AGE=28;


----SQL COMMAND
criteria query for above query is :
List empList = session.createCriteria(Employee.class)
.add( Restrictions.eq("age", new Integer(24) ) )
.add( Restrictions.eq("age", new Integer(28) ) )
.list();

OR Condtion

This method returns the disjuction of two expressions. Any given condition is 'true' then it
executes the query. In this tutorial, "or" is used

// SELECT * FROM EMPLOYEE WHERE AGE=24 OR AGE=28;


----SQL COMMAND
criteria query for above query is :
List empList = session.createCriteria(Employee.class)
.add(Expression.or(
Expression.eq("age", new Integer(24) ) ),
Expression.eq("age", new Integer(28) ) ))
.list();
Hibernate <generator> to generate id (primary key)

The optional <generator> child element names a Java class used to generate unique identifiers
for instances of the persistent class
increment generates identifiers of type long, short or int that are unique only when no other
process is inserting data into the same table. Do not use in a cluster. Follow the setps :

Step 1. create a table name EMPLOYEE in your database

// for MySQL
create table EMPLOYEE (
id bigint(20) ,
name varchar
);
// FOR ORACLE
create table EMPLOYEE (
id number;
name varchar
);

Step 2. Create Emp.java bean class.

Hibernate uses the Plain Old Java Objects (POJOs) classes to map to the database table
(Emp.java to EMPLOYEE TABLE). We can configure the variables to map to the database
column.

public class Emp {


private long id;
private String name;
public long getId() {
return id;
}
private void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

Step 3. Emp.hbm.xml - This mapps EMPLOYEE TABLE and Emp.java : increment for
the generator class
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Emp" table="EMPLOYEE">
<id name="id" column="id" type="long">
<generator class="increment"/> // This generates the primary key
</id>
<property name="name" column="name"/>
</class>
</hibernate-mapping>

Step 4. add Emp.hbm.xml into hibernate.cfg.xml

Hibernate provided connection pooling usning c3p0 and transaction management . Hibernate
uses the hibernate.cfg.xml to create the connection pool and setup required environment

<?xml version='1.0' encoding='utf-8'?>


<lt;!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/techfaqdb</property>
<property name="connection.username">techfaq</property>
<property name="connection.password">techfaq</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="hibernate.c3p0.min_size">1</property>
<property name="hibernate.c3p0.max_size">4</property>
<property name="hibernate.c3p0.timeout">1800</property>
<property name="hibernate.c3p0.max_statements">50</property>
<!-- MySQL dialect//different for different Database -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property
name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<mapping resource="Emp.hbm.xml"/>
</session-factory>
</hibernate-configuration>

Step 5. hibernate automatically increment id using generator

Hibernate Session is the main runtime interface for Hibernate which is used for DataBase
operataion. Session has the method like save () , update () , creteQuery() for Data Base operation.
You can get session using SessionFactory.openSession() method. SessionFactory allows
application to create the Hibernate Sesssion by reading the configuration from hibernate.cfg.xml
file. Then the save () method on session object is used to save the contact information to the
database.

public class TestExample {


public static void main(String[] args) {
Session session = null;
try{ // This step will read hibernate.cfg.xml
SessionFactory sessionFactory = new
Configuration().configure().buildSessionFactory();
session =sessionFactory.openSession();
System.out.println("Inserting Records");
Emp emp1 = new Emp();
emp1.setName("Nick");
session.save(emp1); // We are Not adding id , hibernate automatically
increment the value
Emp emp2 = new Emp();
emp2.setName("Das");
session.save(emp2); // We are Not adding id , hibernate automatically
increment the value
session.flush(); // insert data into databse
System.out.println("Save Done- finish database insert");
// Now fetch the Employee data
List empList = session.createQuery("from Emp").list();
//empList contains the list of Employee
for(int i=0;i
Emp emp = (Emp)empList.get(i);
System.out.println(emp.getId());
System.out.println(emp.getName());
}
// Out put is : 1 Nick 2 Das
}catch(Exception e){
}finally{
session.close();
}
}
}

Prevent concurrent update in Hibernate


This tutorial resolve the issue of User think time : ( one user edit the record for update and
thinking and changing values , same time other user edit the same record and update. then first
user update and 2nd user's data is lost.)
You can say this is version checking in Hibernate or perevent slate object updatation in
Hibernate. version checking used in hibernate when more then one thread trying to access same
data.
For example :
User A edit the row of the TABLE for update ( In the User Interface changing data - This is user
thinking time) and in the same time User B edit the same record for update and click the update.
Then User A click the Update and update done. Chnage made by user B is lost.
In hibernate you can perevent slate object updatation using version checking.
Check the version of the row when you are upding the row.
Get the version of the row when you are fetching the row of the TABLE for update.
On the time of updation just fetch the version number and match with your version number ( on
the time of fetching).
Below steps to prevent concurrent update in Hibernate.

Step 1. Declare a variable "versionId" in your bean Class with setter and getter method.

public class Writer {


private int id;
private String name;
private long versionId; public void setId(int i) {
id = i;
}
public int getId() {
return id;
}
public void setName(String n) {
name = n;
}
public String getName() {
return name;
}
public long getVersionId() {
return versionId;
}
public void setVersionId(long versionId) {
this.versionId = versionId;
}
}

Step 2. Add Extra coulmn name "version" in the WRITER TABLE.

create table WRITER (


ID number, //PRIMARY KEY
NAME varchar,
version number
);
Step 3. Add property in writer.hbm.xml and optimistic-lock="version" - Which maps to
WRITER TABLE.

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Writer" table="WRITER" optimistic-lock="version">
<id name="id" column="ID" type="int" unsaved-value="0">
<generator class="increment"/>
</id>
<property name="name" column="NAME" type="string"/>
<version name="versionId" type="long" column="version" />
</class>
</hibernate-mapping>

Step 4. add writer.hbm.xml into hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>


<lt;!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/techfaqdb</property>
<property name="connection.username">techfaq</property>
<property name="connection.password">techfaq</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="hibernate.c3p0.min_size">1</property>
<property name="hibernate.c3p0.max_size">4</property>
<property name="hibernate.c3p0.timeout">1800</property>
<property name="hibernate.c3p0.max_statements">50</property>
<!-- MySQL dialect//different for different Database -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property
name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<mapping resource="writer.hbm.xml"/>
</session-factory>
</hibernate-configuration>

Step 5. In the Code

When you are updating the table just check the version with you and the current version in the
table.
You can handle StaleObjectStateException() and do what ever you want.
You can display error message.
Hibernate autumatically create/update the version number when you update/insert any row in the
table.

In the code
session = sf.openSession();
long oldVersion = writer.getVersionId();
// User Think time ::::::::::::::: May be 1 minute then get the current
version using load() method below.
session.load( writer, writer.getId() ); // current version in the table
if ( oldVersion!=writer.getVersionId() ) throw new
StaleObjectStateException();
//check the version with you and the current version in the table
writer.setName("Das");
session.flush();
session.connection().commit();
session.close();

Vous aimerez peut-être aussi