Hibernate
Hibernate is a backend framework, free to use, open source developed
purely in java. Its working based on ORM – Object Relational Mapping.
Hibernate framework simplifies the
development of java application to interact with the database. Hibernate is an
open source, lightweight, ORM (Object
Relational Mapping) tool.
An ORM tool simplifies the data creation, data manipulation and data
access. It is a programming technique that maps the object to the data stored
in the data
Advantages of using Hibernate
In place of JDBC we can use hibernate. If we use JDBC to interact with
the database, we need to develop several statements (steps) to send a SQL Query
to the database like registering a driver, establishing a database connection
object, getting a statement object, comparing SQL Query, sending SQL Query to
the database, getting the results from the database, processing those results
and finally closing all the JDBC related resources.
While using hibernate no need for any of these steps, straightaway pass
java object to the hibernate framework. Hibernate framework will take care of
interacting with JDBC API, like registering a driver, establishing a connection
object, composing sql query based on data of java object etc.
Java program will be independent of database code, so we can change the
database like oracle, MySql….. we just have to change one configuration file to
make the changes.
JDBC gets the result immediately after getting the query, it doesn’t
check if the user is using that result or not. In Hibernate it waits till the
user to use that row, then sends the query and gets the result.
Hibernate Architecture There are 4 layers in hibernate
architecture java application layer, hibernate framework layer, backhand api
layer and database layer.Let's see the diagram of hibernate architecture
This is the high level architecture of Hibernate with
mapping file and configuration file.
Hibernate framework uses many objects session factory,
session, transaction etc. alongwith existing Java API such as JDBC (Java
Database Connectivity), JTA (Java Transaction API) and JNDI (Java Naming
Directory Interface).
Elements of Hibernate Architecture For creating the first hibernate
application, we must know the elements of Hibernate architecture. They are as
follows:
|
SessionFactory The SessionFactory is a factory of session and
client of ConnectionProvider. It holds second level cache (optional) of data.
The org.hibernate.SessionFactory interface provides factory method to get the
object of Session.
Session The session object provides
an interface between the application and data stored in the database. It is a
short-lived object and wraps the JDBC connection. It is factory of Transaction,
Query and Criteria. It holds a first-level cache (mandatory) of data. The
org.hibernate.Session interface provides methods to insert, update and delete
the object. It also provides factory methods for Transaction, Query and Criteria.
Transaction The transaction object
specifies the atomic unit of work. It is optional. The
org.hibernate.Transaction interface provides methods for transaction
management.
ConnectionProvider It is a factory of JDBC
connections. It abstracts the application from DriverManager or DataSource. It
is optional.TransactionFactory It is a factory of
Transaction. It is optional.
Two types of loading data from
database in hibernate
Eager Loading
Framework loads data immediately after executing query to get the data,.
Lazy Loading
It does not load data immediately when asked to load, it will be looking
for the statement which is using that data, just before executing that
statement framework will be loading that data.
Hibernate supports both type of loading and the default one is lazy
loading.
Difference between JDBC and Hibernate
In case of JDBC no cache mechanism, no temporary memory to store data.
Every time connects to the db and gets the data (a network flow from java
program to database).
Hibernate supports two levels of cache mechanism: First Level cache and
Second Level.
First level cache is the default. Second level we have to provide
explicitly.
JDBC is not providing any auto increment values to the unique column of
the table. (In general for every table there should be a auto increment
column.) JDBC programmer has to manually increment the unique column(used to
identify the row and count total number of rows).
Hibernate supports auto generated random unique number.
JDBC supports only updatable operations without transactions. No
transaction boundaries required while updating, editing or deleting a row. No
updatable operations without a transaction in case of Hibernate.
E.g.: In a table if column of a particular row are changed at different
statement, Framework updates only at the time of commit statement. It will
update all changes at once. JDBC modifies immediately, even if updating same
row and same column again and again. Hibernate supports Polymorphic mappings
and Association mappings, through this we can easily achieve relationships
among the tables.
Mainly three types of relations among the tables
One-to-one: One row of one table mapping with a particular
row of another table.
One-to-many: One row of 1st table mapping with
multiple rows of 2nd table.
Many-to-many: One row of 1st table mapping with
Multiple rows of 2nd table. One row of 2nd table mapping
with multiple rows of 1st table.
Hibernate supports Annotation mappings
EJB3 and Hibernate developers provide several annotations used for
providing a mapping (easy way of providing a mapping). No need for additional
classes for mapping. Annotation itself contains them, it gives ultimate
performance.
How to use Hibernate Framework
EclipseàNewàProject àJava Project. Project Name: app1
Updating the Build Path:
Right click on app1àPropertiesàJava Build PathàLibrariesàAdd External JARsàBrowse to
Location of the Hibernate un zipped
folder And add all jar files
inside HIBERNATE\hibernate-distribution-4..1.1\lib\required by selecting all.
Again Add the Oracle jdbc driver jar file
D:\oracle\app\oracle\product\10.2.0\server\jdbc\lib\ojdbc14.jar
Copy the hibernate.cfg.xml
and log4j.properties file from
inside Hibernate unzipped bundle go to D:\Java\hibernate\project\tutorials\web\src\main\resources\
Right click on src and paste. The hibernate.cfg.xml is used to identify
the type of database, driver class name, url etc.
The log4j.properties file is not mandatory but is advisable.
While developing for the first time since we won’t be knowing the tags
of the hibernate.cfg.xml file, we are using the model file.
Inside hibernate.cfg.xml file
make the following changes marked in bold:
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<propertyname="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<propertyname="connection.url">jdbc:oracle:thin:@localhost:1521:XE</property>
<propertyname="connection.username">system</property>
<propertyname="connection.password">password</property>
<!-- JDBC connection pool (use the built-in) -->
<propertyname="connection.pool_size">2</property>
<!-- SQL dialect -->
<propertyname="dialect">org.hibernate.dialect.OracleDialect</property>
<!-- Enable Hibernate's current session context -->
<propertyname="current_session_context_class">org.hibernate.context.ManagedSessionContext</property>
<!-- Disable the second-level cache -->
<propertyname="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<propertyname="show_sql">true</property>
<!-- Drop and re-create the database schema on startup
-->
<propertyname="hbm2ddl.auto">create</property>
<mappingresource="com/lara/Person.hbm.xml"/>
</session-factory>
</hibernate-configuration>
|
The SQL dialect specifies the type of database we are using to the
Framework.
Right Click on srcàNewàClass
Person.java (This type of class is called as POJO (Plain Old Java
object) class
package com.lara;
public class Person {
private String id;
private String firstname;
private String lastname;
private int age;
public String getId() {
returnid;
}
public void setId(String id) {
this.id = id;
}
public String getFirstname() {
returnfirstname;
}
public void setFirstname(String
firstname) {
this.firstname = firstname;
}
public String getLastname() {
returnlastname;
}
public void setLastname(String
lastname) {
this.lastname = lastname;
}
publicint getAge() {
returnage;
}
public void setAge(int age) {
this.age = age;
}
}
|
This type of class called useBean in JSP, formBean in Struts and POJO in hibernate.
hibernate\project\tutorials\web\src\main\resources\org\hibernate\tutorial\domain\Person.hbm.xml
and paste it by right clicking on lara folder in eclipse).
Make the following changes in Person.hbm.xml
<hibernate-mappingpackage="com.lara">
<classname="Person"table="PERSON">
<idname="id"column="PERSON_ID">
<generatorclass="native"/>
</id>
<propertyname="age"/>
<propertyname="firstname"/>
<propertyname="lastname"column="last_name"/>
</class>
</hibernate-mapping>
|
Manager.java
package com.lara;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Manager {
public static void main(String[] args) {
Person p1 = new Person();
p1.setFirstname("abc");
p1.setLastname("xyz");
p1.setAge(25);
Configuration c1 = new Configuration();
c1.configure();
SessionFactory sf = c1.buildSessionFactory();
Session session = sf.openSession();
}
}
|
SQL query sent to db
CREATE TABLE
"PERSON"
( "PERSON_ID"
VARCHAR2(255) NOT NULL ENABLE,
"AGE" NUMBER(10,0),
"FIRSTNAME" VARCHAR2(255),
"LAST_NAME" VARCHAR2(255),
PRIMARY KEY ("PERSON_ID") ENABLE
)
/
|
Manager classs :
package com.lara;
import java.util.Scanner;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
public class
Manager1
{
public static
void main(String[] args)
{
Configuration con = new Configuration();
con.configure();
ServiceRegistry sr = new ServiceRegistryBuilder().
applySettings(con.getProperties()).build();
SessionFactory sf =
con.buildSessionFactory(sr);
Session s1 = sf.openSession();
/* Person p1 = new Person();
p1.setFirstName("lara");
p1.setLastName("rst");
p1.setAge(22);
Person p2 = new
Person();
p2.setFirstName("vijay");
p2.setLastName("kumar");
p2.setAge(26);
s1.beginTransaction();
s1.save(p1);
s1.save(p2);
s1.getTransaction().commit();
s1.flush();
s1.close(); */
By using Sccanner class :
/* Scanner sc = new Scanner(System.in);
String firstName,
lastName, decider;
int age;
Person p1 = null;
s1.beginTransaction();
do
{
p1= new Person();
System.out.println("Enter
first name : ");
p1.setFirstName(sc.next());
System.out.println("Enter
last name : ");
p1.setLastName(sc.next());
System.out.println("Enter
age : ");
p1.setAge(sc.nextInt());
s1.save(p1);
System.out.println("Do
you want to save one more y/n : ");
decider = sc.next();
}while("y".equals(decider));
s1.getTransaction().commit(); */
/* Person p1 = (Person)s1.load(Person.class, 1);
//Person p1 =
(Person)s1.get(Person.class, 2);
System.out.println(p1.getId()+
" - " +p1.getFirstName()+ " - "
+p1.getLastName()+
" - "+p1.getAge());*/
/* Person p2 = (Person)s1.load(Person.class, 2);
p2.setFirstName("hello");
p2.setLastName("test");
s1.beginTransaction();
s1.update(p2);
s1.getTransaction().commit();
*/
/* Person p3 = (Person)s1.load(Person.class, 1);
s1.beginTransaction();
s1.delete(p3);
s1.getTransaction().commit();
System.out.println("
done ");*/
}
}
Transaction
Interface in Hibernate In hibernate framework, we have Transaction interface that defines the unit of work. It maintains
abstraction from the transaction implementation (JTA,JDBC).
A transaction is associated with Session and instantiated by
calling session.beginTransaction().
The methods of Transaction interface are as follows:
void begin() starts a new transaction.
void commit() ends the unit of work unless we are in
FlushMode.NEVER.
void rollback() forces this transaction to rollback.
void setTimeout(int seconds) it sets a transaction timeout for any
transaction started by a subsequent call to begin on this instance.
boolean isAlive() checks if the transaction is still
alive.
void
registerSynchronization(Synchronization s) registers a user synchronization
callback for this transaction.
boolean wasCommited() checks if the transaction is commited
successfully.
HCQL (Hibernate Criteria Query Language)
The Hibernate Criteria Query Language (HCQL) is used to
fetch the records based on the specific criteria.
Criteria Interface
The Criteria interface provides many methods to specify
criteria. The object of Criteria can be obtained by calling the createCriteria() method of Session interface.
Syntax of createCriteria()
method of Session interface
public Criteria createCriteria(Class c)
The commonly used methods of Criteria interface are as
follows:
public Criteria add(Criterion c) is used to add restrictions.
public Criteria addOrder(Order o) specifies ordering.
public Criteria setFirstResult(int
firstResult) specifies
the first number of record to be retreived.
public Criteria setMaxResult(int
totalResult) specifies
the total number of records to be retreived.
public List list() returns list containing object.
public Criteria
setProjection(Projection projection) specifies the projection.
Example :
Criteria ctr = s1.createCriteria(Person.class);
ctr.add(Restrictions.eq("firstName",
"lara"));
ctr.add(Restrictions.gt("age", 15));
ctr.add(Restrictions.like("lastName",
"%s%"));
List<Person> list = ctr.list()
Example2 :
Criteria ctr = s1.createCriteria(Person.class);
Criterion c1 =
Restrictions.eq("firstName", "lara");
//ctr.add(c1);
Criterion c2 = Restrictions.gt("age",
25);
Criterion c3 = Restrictions.or(c1, c2);
ctr.add(c3);
List<Person> list = ctr.list();
Example 3
List<Person> list =
s1.createCriteria(Person.class).add(Restrictions.gt("age",
25)).list();
for (Person p1
: list)
{
System.out.println(p1.getId()+ " -
" +p1.getFirstName()+ " - "
+p1.getLastName()+ " - " +p1.getAge());
System.out.println("------------");
}
createSQLQuery():
List<Object[]> list2 =
s1.getNamedQuery("q1").list();
//List<Object[]> list2 = s1.getNamedQuery("q2").list();
//List<Object[]> list2 =
s1.getNamedQuery("q3").setInteger("param1", 22).list(); List<Object[]> list2 =
s1.getNamedQuery("q4").setInteger("param1",21).setString("param2",
"hello").list();
for (Object[]
row : list2)
{
System.out.println(Arrays.toString(row));
System.out.println("-------");
}
HQL queary : Hibernate
Query Language (HQL) is same as SQL (Structured Query Language) but it doesn't
depends on the table of the database. Instead of table name, we use class name in
HQL. So it is database independent query language.
Advantage of HQL
There are many advantages of HQL. They are as follows:
database independent
supports polymorphic queries
easy to learn for Java Programmer
Query Interface It is an object oriented representation of Hibernate Query.
The object of Query can be obtained by calling the createQuery() method Session
interface. The query interface provides many methods. There is given commonly
used methods:
public int executeUpdate() is used to execute the update or delete
query.
public List list() returns the result of the ralation as a
list.
public Query setFirstResult(int rowno) specifies the row number from where
record will be retrieved.
public Query setMaxResult(int rowno) specifies the no. of records to be
retrieved from the relation (table).
public Query setParameter(int position,
Object value) it sets the value to the JDBC style query parameter.
public Query setParameter(String name,
Object value) it sets the value to a named query parameter.
Examples :
Query query =
s1.createQuery("from Person");
Exp-1
Query query =
s1.createQuery("from com.lara.Person where firstName = 'lara'");
Exp-2
Query query =
s1.createQuery("from com.lara.Person where age < 25 or
firstName =
'lara'");
List<Person>
list3 = query.list();
for (Person p1 : list3)
{
System.out.println(p1.getId()+
" - " +p1.getFirstName()+ " - "
+p1.getLastName()+
" - " +p1.getAge());
System.out.println("----------");
}
Exp-3
Query query =
s1.createQuery("select firstName from com.lara.Person");
List<String>
list3 = query.list();
for (String p1 : list3)
{
System.out.println(p1);
System.out.println("--------");
}
Exp-4
Query query =
s1.createQuery("select firstName, lastName from com.lara.Person");
List<Object []>
list3 = query.list();
for (Object[] p1 :
list3)
{
System.out.println(Arrays.toString(p1));
System.out.println("--------");
}
Hibernate Named Query
The hibernate named query is way to use any query by some meaningful
name. It is like using alias names. The Hibernate framework provides the
concept of named queries so that application programmer need not to scatter
queries to all the java code.
There are two ways to define the named query in hibernate:
by annotation
by mapping file.
BY using annotations : @NameQueries annotation is used to define the
multiple named queries. @NameQuery annotation is used to define the
single named query.
Inside manager class
getNamedQuery()- Using
Annotation
//List<Object[]>
list2 = s1.getNamedQuery("q1").list();
//List<Person>
list2 = s1.getNamedQuery("q2").list();
//List<Person>
list2 = s1.getNamedQuery("q3").setInteger("param1",
22).list();
List<Person>list2
=
s1.getNamedQuery("q4").setInteger("param1",20).setString("param2","rst").list();
for (Person p1 : list2)
{
System.out.println(p1.getId()+
" - " +p1.getFirstName()+ " - "
+p1.getLastName()+
" - "+p1.getAge());
System.out.println("-------");
}
New Java Project: app2
Update Java Build Path with jdbc driver, hibernate.jar and jar files in
required folder. hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<propertyname="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<propertyname="connection.url">jdbc:oracle:thin:@localhost:1521:XE</property>
<propertyname="connection.username">system</property>
<propertyname="connection.password">password</property>
<!-- JDBC connection pool (use the built-in) -->
<propertyname="connection.pool_size">2</property>
<!-- SQL dialect -->
<propertyname="dialect">org.hibernate.dialect.OracleDialect</property>
<!-- Enable Hibernate's current session context -->
<propertyname="current_session_context_class">org.hibernate.context.ManagedSessionContext</property>
<!-- Disable the second-level cache -->
<propertyname="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<propertyname="show_sql">true</property>
<!-- Drop and re-create the database schema on startup
-->
<propertyname="hbm2ddl.auto">create</property>
<mappingresource="com/lara/entity/Person.hbm.xml"/>
</session-factory>
</hibernate-configuration>
|
New class HibernatUtil in app2/src/com/lara/util/
package com.lara.util;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
public class HibernateUtil {
private static Session session = null;
//java program interacts with the Framework libraries through
session obj.
static{ //initialize
session object
Configuration config = new Configuration();
config.configure(); //looks for hibernate.cfg.xml inside classpath.
//src folder will be in classpath of eclipse.
SessionFactory sf = config.buildSessionFactory();
session = sf.openSession();
}
public static Session getSession()
{
returnsession;
}
public static void closeSession()
{
session.flush();
session.close();
}
}
|
Person.java in com/lara/entity (POJO class)
package com.lara.entity;
public class Person {
privateintpersonId;
private String firstName, lastName;
privateintage;
private String email;
publicint getPersonId() {
returnpersonId;
}
public void setPersonId(int personId) {
this.personId = personId;
}
public String getFirstName() {
returnfirstName;
}
public void setFirstName(String
firstName) {
this.firstName = firstName;
}
public String getLastName() {
returnlastName;
}
public void setLastName(String
lastName) {
this.lastName = lastName;
}
publicint getAge() {
returnage;
}
public void setAge(int age) {
this.age = age;
}
public String getEmail() {
returnemail;
}
public void setEmail(String email) {
this.email = email;
}
}
|
For every POJO class we need one .hbm.xml file. It provides mapping
between class_name and table name attribute. We can keep the hbm file in any
location inside src folder with any name.
Create the Person.hbm.xml file inside entity folder (copy & paste).
app2/src/com/lara/entity/Person.hbm.xml
<hibernate-mappingpackage="com.lara.entity">
<classname="Person"table="PERSON">
<idname="personId"column="PERSON_ID">
<generatorclass="native"/>
</id>
<propertyname="age"/>
<propertyname="firstName"column="first_name"/>
<propertyname="lastName"column="last_name"/>
<propertyname="email"/>
</class>
</hibernate-mapping>
|
If column name is not provided we get the column name as the attribute
name. so for age and email we get the column name as age and email only.
The <id> tag is used to provide primary key value. The personId is
qualifying as a primary key column.
app2/src/com/lara/client/Manager1 (To demonstrate create and update operation)
package com.lara.client;
import org.hibernate.Session;
import com.lara.entity.Person;
import com.lara.util.HibernateUtil;
public class Manager1 {
public static void main(String[] args) {
Person p1 = new Person();
p1.setFirstName("Shiva");
p1.setLastName("Great Indian");
p1.setAge(23);
p1.setEmail("Shiva@lara.co.in");
//hibernate FW automatically provides auto incremented
id.
Session session = HibernateUtil.getSession();
session.beginTransaction();
session.save(p1); //save Person obj. inside session obj.
session.getTransaction().commit();
HibernateUtil.closeSession();
}
}
|
Hibernate checks for Person table, if present drops
it and creates new table.
Output console:
Hibernate: select hibernate_sequence.nextval from dual
Hibernate: insert into PERSON (age,
first_name, last_name, email, PERSON_ID) values (?, ?, ?, ?, ?)
|
Query
CREATE TABLE "PERSON"
( "PERSON_ID" NUMBER(10,0) NOT NULL ENABLE,
"AGE" NUMBER(10,0),
"FIRST_NAME" VARCHAR2(255),
"LAST_NAME" VARCHAR2(255),
"EMAIL" VARCHAR2(255),
PRIMARY KEY ("PERSON_ID") ENABLE
)
/
|
To insert data into same table in multiple execution (update operation).
Change the <propertyname="hbm2ddl.auto">create</property>create
to update.
As shown:<propertyname="hbm2ddl.auto">update</property>
The create type
Drop’s and re-creates the database table.
The update type
inserts a new row to the table on each execution. Generating a new unique
Persion_ID for each row.
To demonstrate
load operation
app2/src/com/lara/client/Manager2.java
package com.lara.client;
import org.hibernate.Session;
import com.lara.entity.Person;
import com.lara.util.HibernateUtil;
public class Manager2 {
public static void main(String[] args) {
Session session = HibernateUtil.getSession();
Person p1 = (Person) session.load(com.lara.entity.Person.class, 2);
//load one row having unique id as 2 into java program
System.out.println(10);
System.out.println(p1.getPersonId());
System.out.println(20);
System.out.println(p1.getFirstName());
System.out.println(30);
System.out.println(p1.getLastName());
System.out.println(p1.getAge());
System.out.println(p1.getEmail());
}
}
|
Output:
10
2
20
Hibernate: select person0_.PERSON_ID as PERSON1_0_0_,
person0_.age as age0_0_, person0_.first_name as first3_0_0_,
person0_.last_name as last4_0_0_, person0_.email as email0_0_ from PERSON
person0_ where person0_.PERSON_ID=?
Shiva
30
Great Indian
23
Shiva@lara.co.in
|
While calling load
or getPerson SELECT Query is not triggered. Before calling getFirstName select
query is triggered. Till then firstName, lastName, age, email not available in
Person object. After query is executed gets the values from database and stores
them in Person object.
Initially Person
object defined only with Person_Id.
This concept is
called as Lazy loading.
To force the
triggering of SELECT query on execution of load or getter methods, make the
following changes inside the Person.hbm.xml file:
<classname="Person"table="PERSON"lazy="false">
Output:
Hibernate: select person0_.PERSON_ID as PERSON1_0_0_,
person0_.age as age0_0_, person0_.first_name as first3_0_0_,
person0_.last_name as last4_0_0_, person0_.email as email0_0_ from PERSON
person0_ where person0_.PERSON_ID=?
10
2
20
Shiva
30
Great Indian
23
Shiva@lara.co.in
|
Query executed on
calling load()method inside session object itself.
If we pass an Id
that does not exist, we get ObjectNotFoundException.
Exception in thread "main" org.hibernate.ObjectNotFoundException: No row with the given identifier
exists: [com.lara.entity.Person#5]
We can also use
get method instead of the load method, while getting the values to p1 Person
object
Person p1 = (Person) session.get(com.lara.entity.Person.class, 1);
The output will be same as while using
load.
But if we use get to a row that does not exist, i.e., if we pass an Id that does
not exist using get method, we get NullPointerException.
Exception in thread "main" java.lang.NullPointerException
Difference between load and get is:
If row is not available, load gives ObjectNotFoundException and get gives NullPointerException.
The get method just returns null, does
not generate any Exception object.
The load method will be raising an
exception, which creates and exception object and which in turn returns ONFE.
Best practice is to use get method and
if p1 reference variable not pointing to any object, i.e., if p1 is null, don’t
call get method.
Person p1 = (Person) session.get(com.lara.entity.Person.class, 10);
Here p1 will get a null because 10th
row (row with Person_Id as 10) does not exist.
package com.lara.client;
public class Manager2 {
public static void main(String[] args) {
Session session = HibernateUtil.getSession();
Person p1 = (Person) session.get(com.lara.entity.Person.class, 10);
if(p1 != null)
{
System.out.println(10);
System.out.println(p1.getPersonId());
System.out.println(20);
System.out.println(p1.getFirstName());
System.out.println(30);
System.out.println(p1.getLastName());
System.out.println(p1.getAge());
System.out.println(p1.getEmail());
}
else
{
System.out.println("No row available with id as 10");
}
}
}
|
Output:
Hibernate: select person0_.PERSON_ID as PERSON1_0_0_,
person0_.age as age0_0_, person0_.first_name as first3_0_0_,
person0_.last_name as last4_0_0_, person0_.email as email0_0_ from PERSON
person0_ where person0_.PERSON_ID=?
No row available with id as 10
|
Manager3.java in app2/com/lara/client
package com.lara.client;
import org.hibernate.Session;
import com.lara.entity.Person;
import com.lara.util.HibernateUtil;
public class Manager3 {
public static void main(String[] args) {
Session session = HibernateUtil.getSession();
Person p1 = (Person) session.load(com.lara.entity.Person.class, 3);
session.beginTransaction();
p1.setLastName("new lastname"); //modifies column
session.saveOrUpdate(p1);
p1.setAge(90);
session.saveOrUpdate(p1);
p1.setFirstName("new Kiran");
session.saveOrUpdate(p1);
session.getTransaction().commit();
HibernateUtil.closeSession();
}
}
|
getTransaction method is required for
all updatable operations like update or delete.
Update triggered only once even though
we called 3 times. Its triggered while committing Transaction.
Initially changes are stored in the
Person object p1, which is in session object. When commit is executed, its
moved from session object to database.
Manager4.java in
app2/src/com/lara/client
package com.lara.client;
import org.hibernate.Session;
import com.lara.entity.Person;
import com.lara.util.HibernateUtil;
public class Manager4 {
public static void main(String[] args) {
Session session = HibernateUtil.getSession();
Person p1 = (Person) session.load(com.lara.entity.Person.class, 3);
Person p2 = (Person) session.load(com.lara.entity.Person.class, 3);
Person p3 = (Person) session.load(com.lara.entity.Person.class, 3);
Person p4 = (Person) session.load(com.lara.entity.Person.class, 3);
Person p5 = (Person) session.load(com.lara.entity.Person.class, 3);
HibernateUtil.closeSession();
} }
|
Output:
Hibernate: select person0_.PERSON_ID as PERSON1_0_0_, person0_.age as
age0_0_, person0_.first_name as first3_0_0_, person0_.last_name as last4_0_0_,
person0_.email as email0_0_ from PERSON person0_ where person0_.PERSON_ID=?
SELECT query is triggered only once.
After triggering for the 1st time, gets the data and stores in
Person object inside session object. So from 2nd time onwards loads
the values from the session object and won’t send the query.
This is called as First Level cache
Management.
Manager5.java in
app2/src/com/lara/client
package com.lara.client;
import org.hibernate.Transaction;
import org.hibernate.Session;
import com.lara.entity.Person;
import com.lara.util.HibernateUtil;
public class Manager5 {
public static void main(String[] args) {
Session session = HibernateUtil.getSession();
Person p1 = (Person) session.load(com.lara.entity.Person.class, 2);
Transaction tx = session.beginTransaction();
session.delete(p1);
session.delete(p1);
session.delete(p1);
tx.commit();
}
}
|
Delete query triggered only once, that
too after commit.
Session
object methods:
save, update, saveOrUpdate, delete.
Hibernate is using methods of session
object. Except read, all methods should be inside Transaction object.
If transaction object not used, use
session.getTransaction().commit();
instead of the tx.commit();
Book.java inside app2/com/lara/entity/
(POJO class)
package com.lara.entity;
public class Book {
privateintbookId;
private String title, author;
publicint getBookId() {
returnbookId;
}
public void setBookId(int bookId) {
this.bookId = bookId;
}
public String getTitle() {
returntitle;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
returnauthor;
}
public void setAuthor(String author)
{
this.author = author;
}
}
|
In the Person.hbm.xml file:
<hibernate-mappingpackage="com.lara.entity">
<classname="Book"table="BOOK"lazy="false">
<idname="bookId"column="BOOK_ID">
<generatorclass="native"/>
</id>
<propertyname="age"/>
<propertyname="title"/>
<propertyname="author"/>
</class>
</hibernate-mapping>
|
Update in cfg.xml file, if not updated.
Manager6 in app2/src/com/lara/client
package com.lara.client;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.lara.entity.Book;
import com.lara.util.HibernateUtil;
public class Manager6 {
public static void main(String[] args) {
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
Book b1 = new Book();
b1.setTitle("Java Made Easy");
b1.setAuthor("Shiva");
session.save(b1);
session.save(b1);
session.save(b1);
session.save(b1);
tx.commit();
}
}
|
Make sure there isn’t a BOOK table in
db before executing Manager6.
Output: INSERT query only at the time
of commit that too only once.
If <generatorclass="native"/>in .hbm.xml file is native, then only one sequence will be used for all
the Tables which are interacting through hibernate.
The sequence is hibernate_sequence. For example if
the unique Id for a row in one table is 22, and if we add another row in
another table, then its unique id will be 23 and so on. It uses common auto
increment sequence for all tables.
If row count common across all table go for
generator class=”native”.
We can use a separate hbm file Book class
Create com/lara/entity/Book.hbm.xml file and save.
<hibernate-mappingpackage="com.lara.entity">
<classname="Book"table="BOOK"lazy="false">
Update in cfg.xml
<mappingresource="com/lara/entity/Person.hbm.xml"/>
<mappingresource="com/lara/entity/BOOK.hbm.xml"/>
We can have any number of mapping resource in
cfg.xml file.
Always use separate mapping files for each Pojo
class.
Manager6
package com.lara.client;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.lara.entity.Book;
import com.lara.util.HibernateUtil;
public class Manager6 {
public static void main(String[] args) {
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
Book b1 = new Book();
b1.setTitle("Hibernate Made Easy");
b1.setAuthor("Shiva");
session.save(b1);
tx.commit();
}
}
|
SELECT Max(Book_ID): reads Max. value of present
BOOk_ID and increments that and assigns
as Unique ID.
All generator classes not supported by all
databases.For example “identity” generator class not supported by oracle.
<generatorclass="identity"/>
Sequence:
<generator class="sequence"/>
Same as native.
hilo
<generatorclass="hilo"/>
Randomly generates one unique Id, using its own
algorithm.
seqhilo
<generatorclass="seqhilo"/>
Applies the hilo algorithm to the sequence value of
hibernate_native.
uuid
<generatorclass="uuid"/>
Unique id as a string. Change bookId to String
type. Also change hbm2dll to create in hibernate.cfg.xml.<propertyname="hbm2ddl.auto">create</property>
Generates one String content for Book_Id.
Guid
<generator class="guid"/>
Here also a String is generated of id.
assigned
<generatorclass="assigned"/>
The framework (generator class) won’t provide any
ID. We have to set explicitly through setter methods. For example:
b1.setBookId(“b101”);
No comments:
Post a Comment