Aejp Unit IV
Aejp Unit IV
Hibernate - Overview
Hibernate maps Java classes to database tables and from Java data types to SQL data types and
relieves the developer from 95% of common data persistence related programming tasks.
Hibernate sits between traditional Java objects and database server to handle all the works in
persisting those objects based on the appropriate O/R mechanisms and patterns.
Hibernate Advantages
Hibernate takes care of mapping Java classes to database tables using XML files and
without writing any line of code.
Provides simple APIs for storing and retrieving Java objects directly to and from the
database.
If there is change in the database or in any table, then you need to change the XML file
properties only.
Abstracts away the unfamiliar SQL types and provides a way to work around familiar
Java Objects.
Hibernate does not require an application server to operate.
Manipulates Complex associations of objects of your database.
Minimizes database access with smart fetching strategies.
Provides simple querying of data.
Supported Databases
Hibernate supports almost all the major RDBMS. Following is a list of few of the database
engines supported by Hibernate −
Supported Technologies
XDoclet Spring
J2EE
Eclipse plug-ins
Maven
Hibernate - Architecture
Hibernate has a layered architecture which helps the user to operate without having to know the
underlying APIs. Hibernate makes use of the database and configuration data to provide
persistence services (and persistent objects) to the application.
Hibernate uses various existing Java APIs, like JDBC, Java Transaction API(JTA), and Java
Naming and Directory Interface (JNDI). JDBC provides a rudimentary level of abstraction of
functionality common to relational databases, allowing almost any database with a JDBC driver
to be supported by Hibernate. JNDI and JTA allow Hibernate to be integrated with J2EE
application servers.
Following section gives brief description of each of the class objects involved in Hibernate
Application Architecture.
Configuration Object
The Configuration object is the first Hibernate object you create in any Hibernate application. It
is usually created only once during application initialization. It represents a configuration or
properties file required by the Hibernate.
SessionFactory Object
Configuration object is used to create a SessionFactory object which in turn configures Hibernate
for the application using the supplied configuration file and allows for a Session object to be
instantiated. The SessionFactory is a thread safe object and used by all the threads of an
application.
The SessionFactory is a heavyweight object; it is usually created during application start up and
kept for later use. You would need one SessionFactory object per database using a separate
configuration file. So, if you are using multiple databases, then you would have to create
multiple SessionFactory objects.
Session Object
A Session is used to get a physical connection with a database. The Session object is lightweight
and designed to be instantiated each time an interaction is needed with the database. Persistent
objects are saved and retrieved through a Session object.
The session objects should not be kept open for a long time because they are not usually thread
safe and they should be created and destroyed them as needed.
Transaction Object
A Transaction represents a unit of work with the database and most of the RDBMS supports
transaction functionality. Transactions in Hibernate are handled by an underlying transaction
manager and transaction (from JDBC or JTA).
This is an optional object and Hibernate applications may choose not to use this interface, instead
managing transactions in their own application code.
Query Object
Query objects use SQL or Hibernate Query Language (HQL) string to retrieve data from the
database and create objects. A Query instance is used to bind query parameters, limit the number
of results returned by the query, and finally to execute the query.
Criteria Object
Criteria objects are used to create and execute object oriented criteria queries to retrieve objects.
ORM Frameworks
Hibernate
TopLink
ORMLite
iBATIS
JPOX
Mapping Directions
Unidirectional relationship - In this relationship, only one entity can refer the properties
to another. It contains only one owing side that specifies how an update can be made in
the database.
Bidirectional relationship - This relationship contains an owning side as well as an
inverse side. So here every entity has a relationship field or refer the property to other
entity.
Types of Mapping
We can map collection elements of Persistent class in Hibernate. You need to declare the type of
collection in Persistent class from one of the following types:
java.util.List
java.util.Set
java.util.SortedSet
java.util.Map
java.util.SortedMap
java.util.Collection
or write the implementation of org.hibernate.usertype.UserCollectionType
The persistent class should be defined like this for collection element.
1. package com.javatpoint;
2.
3. import java.util.List;
4.
5. public class Question {
6. private int id;
7. private String qname;
8. private List<String> answers;//List can be of any type
9.
10. //getters and setters
11.
12. }
There are many subelements of <class> elements to map the collection. They are <list>, <bag>,
<set> and <map>. Let's see how we implement the list for the above class:
<key> element is used to define the foreign key in this table based on the Question class
identifier.
<index> element is used to identify the type. List and Map are indexed collection.
<element> is used to define the element of the collection.
This is the mapping of collection if collection stores string objects. But if collection stores entity
reference (another class objects), we need to define <one-to-many> or <many-to-many>
element. Now the Persistent class will look like:
1. package com.javatpoint;
2.
3. import java.util.List;
4.
5. public class Question {
6. private int id;
7. private String qname;
8. private List<Answer> answers;//Here, List stores the objects of Answer class
9.
10. //getters and setters
11.
12. }
1. package com.javatpoint;
2. import java.util.List;
3. public class Answer {
4. private int id;
5. private String answer;
6. private String posterName;
7. //getters and setters
8. }
Here, List is mapped by one-to-many relation. In this scenario, there can be many answers for
one question.
The key element is used to define the foreign key in the joined table based on the original
identity. The foreign key element is nullable by default. So for non-nullable foreign key, we need
to specify not-null attribute such as:
The attributes of the key element are column, on-delete, property-ref, not-null, update and
unique.
1. <key
2. column="columnname"
3. on-delete="noaction|cascade"
4. not-null="true|false"
5. property-ref="propertyName"
6. update="true|false"
7. unique="true|false"
8. />
Indexed collections
indexed ,and
non-indexed
The List and Map collection are indexed whereas set and bag collections are non-indexed. Here,
indexed collection means List and Map requires an additional element <index>.
Collection Elements
The collection elements can have value or entity reference (another class object). We can use one
of the 4 elements
element
component-element
one-to-many, or
many-to-many
The element and component-element are used for normal value such as string, int etc. whereas
one-to-many and many-to-many are used to map entity reference.
Association Mappings
Introduction
Association mappings are often the most difficult thing to implement correctly. In this section we
examine some canonical cases one by one, starting with unidirectional mappings and then
bidirectional cases. We will use Person and Address in all the examples.
Associations will be classified by multiplicity and whether or not they map to an intervening join
table.
Nullable foreign keys are not considered to be good practice in traditional data modelling, so our
examples do not use nullable foreign keys. This is not a requirement of Hibernate, and the
mappings will work if you drop the nullability constraints.
Unidirectional associations
1. Many-to-one
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<many-to-one name="address"
column="addressId"
not-null="true"/>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
</class>
create table Person ( personId bigint not null primary key, addressId bigint not null )
create table Address ( addressId bigint not null primary key )
2. One-to-one
A unidirectional one-to-one association on a foreign key is almost identical. The only difference
is the column unique constraint.
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<many-to-one name="address"
column="addressId"
unique="true"
not-null="true"/>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
</class>
create table Person ( personId bigint not null primary key, addressId bigint not null unique )
create table Address ( addressId bigint not null primary key )
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
</class>
<class name="Address">
<id name="id" column="personId">
<generator class="foreign">
<param name="property">person</param>
</generator>
</id>
<one-to-one name="person" constrained="true"/>
</class>
create table Person ( personId bigint not null primary key )
create table Address ( personId bigint not null primary key )
3. One-to-many
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<set name="addresses">
<key column="personId"
not-null="true"/>
<one-to-many class="Address"/>
</set>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
</class>
create table Person ( personId bigint not null primary key )
create table Address ( addressId bigint not null primary key, personId bigint not null )
You should instead use a join table for this kind of association.
1. One-to-many
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<set name="addresses" table="PersonAddress">
<key column="personId"/>
<many-to-many column="addressId"
unique="true"
class="Address"/>
</set>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
</class>
create table Person ( personId bigint not null primary key )
create table PersonAddress ( personId not null, addressId bigint not null primary key )
create table Address ( addressId bigint not null primary key )
2. Many-to-one
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<join table="PersonAddress"
optional="true">
<key column="personId" unique="true"/>
<many-to-one name="address"
column="addressId"
not-null="true"/>
</join>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
</class>
create table Person ( personId bigint not null primary key )
create table PersonAddress ( personId bigint not null primary key, addressId bigint not null )
create table Address ( addressId bigint not null primary key )
3. One-to-one
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<join table="PersonAddress"
optional="true">
<key column="personId"
unique="true"/>
<many-to-one name="address"
column="addressId"
not-null="true"
unique="true"/>
</join>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
</class>
create table Person ( personId bigint not null primary key )
create table PersonAddress ( personId bigint not null primary key, addressId bigint not null
unique )
create table Address ( addressId bigint not null primary key )
4. Many-to-many
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<set name="addresses" table="PersonAddress">
<key column="personId"/>
<many-to-many column="addressId"
class="Address"/>
</set>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
</class>
create table Person ( personId bigint not null primary key )
create table PersonAddress ( personId bigint not null, addressId bigint not null, primary key
(personId, addressId) )
create table Address ( addressId bigint not null primary key )
4. Bidirectional associations
1. one-to-many / many-to-one
A bidirectional many-to-one association is the most common kind of association. The following
example illustrates the standard parent/child relationship.
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<many-to-one name="address"
column="addressId"
not-null="true"/>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
<set name="people" inverse="true">
<key column="addressId"/>
<one-to-many class="Person"/>
</set>
</class>
create table Person ( personId bigint not null primary key, addressId bigint not null )
create table Address ( addressId bigint not null primary key )
If you use a List, or other indexed collection, set the key column of the foreign key to not null.
Hibernate will manage the association from the collections side to maintain the index of each
element, making the other side virtually inverse by setting update="false" and insert="false":
<class name="Person">
<id name="id"/>
...
<many-to-one name="address"
column="addressId"
not-null="true"
insert="false"
update="false"/>
</class>
<class name="Address">
<id name="id"/>
...
<list name="people">
<key column="addressId" not-null="true"/>
<list-index column="peopleIdx"/>
<one-to-many class="Person"/>
</list>
</class>
If the underlying foreign key column is NOT NULL, it is important that you define not-
null="true" on the <key> element of the collection mapping. Do not only declare not-null="true"
on a possible nested <column> element, but on the <key> element.
2. One-to-one
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<many-to-one name="address"
column="addressId"
unique="true"
not-null="true"/>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
<one-to-one name="person"
property-ref="address"/>
</class>
create table Person ( personId bigint not null primary key, addressId bigint not null unique )
create table Address ( addressId bigint not null primary key )
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<one-to-one name="address"/>
</class>
<class name="Address">
<id name="id" column="personId">
<generator class="foreign">
<param name="property">person</param>
</generator>
</id>
<one-to-one name="person"
constrained="true"/>
</class>
create table Person ( personId bigint not null primary key )
create table Address ( personId bigint not null primary key )
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<set name="addresses"
table="PersonAddress">
<key column="personId"/>
<many-to-many column="addressId"
unique="true"
class="Address"/>
</set>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
<join table="PersonAddress"
inverse="true"
optional="true">
<key column="addressId"/>
<many-to-one name="person"
column="personId"
not-null="true"/>
</join>
</class>
create table Person ( personId bigint not null primary key )
create table PersonAddress ( personId bigint not null, addressId bigint not null primary key )
create table Address ( addressId bigint not null primary key )
2. one to one
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<join table="PersonAddress"
optional="true">
<key column="personId"
unique="true"/>
<many-to-one name="address"
column="addressId"
not-null="true"
unique="true"/>
</join>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
<join table="PersonAddress"
optional="true"
inverse="true">
<key column="addressId"
unique="true"/>
<many-to-one name="person"
column="personId"
not-null="true"
unique="true"/>
</join>
</class>
create table Person ( personId bigint not null primary key )
create table PersonAddress ( personId bigint not null primary key, addressId bigint not null
unique )
create table Address ( addressId bigint not null primary key )
3. Many-to-many
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<set name="addresses" table="PersonAddress">
<key column="personId"/>
<many-to-many column="addressId"
class="Address"/>
</set>
</class>
<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
<set name="people" inverse="true" table="PersonAddress">
<key column="addressId"/>
<many-to-many column="personId"
class="Person"/>
</set>
</class>
create table Person ( personId bigint not null primary key )
create table PersonAddress ( personId bigint not null, addressId bigint not null, primary key
(personId, addressId) )
create table Address ( addressId bigint not null primary key )
More complex association mappings
More complex association joins are extremely rare. Hibernate handles more complex situations
by using SQL fragments embedded in the mapping document. For example, if a table with
historical account information data defines accountNumber, effectiveEndDate and
effectiveStartDatecolumns, it would be mapped as follows:
<properties name="currentAccountKey">
<property name="accountNumber" type="string" not-null="true"/>
<property name="currentAccount" type="boolean">
<formula>case when effectiveEndDate is null then 1 else 0 end</formula>
</property>
</properties>
<property name="effectiveEndDate" type="date"/>
<property name="effectiveStateDate" type="date" not-null="true"/>
You can then map an association to the current instance, the one with null effectiveEndDate, by
using:
<many-to-one name="currentAccountInfo"
property-ref="currentAccountKey"
class="AccountInfo">
<column name="accountNumber"/>
<formula>'1'</formula>
</many-to-one>
In a more complex example, imagine that the association between Employee and Organization is
maintained in an Employment table full of historical employment data. An association to the
employee's most recent employer, the one with the most recent startDate, could be mapped in the
following way:
<join>
<key column="employeeId"/>
<subselect>
select employeeId, orgId
from Employments
group by orgId
having startDate = max(startDate)
</subselect>
<many-to-one name="mostRecentEmployer"
class="Organization"
column="orgId"/>
</join>
This functionality allows a degree of creativity and flexibility, but it is more practical to handle
these kinds of cases using HQL or a criteria query.
A Component mapping is a mapping for a class having a reference to another class as a member
variable. We have seen such mapping while having two tables and using <set> element in the
mapping file. Now we will use <component> element in the mapping file and a single table
would be used to keep the attributes contained inside the class variable.
Consider a situation where we need to store our employee records in EMPLOYEE table which
will have following structure −
Further, assume each employee will have an address, so let us add address specific fields in the
same table as follows −
Let us implement our POJO class Employee, which will be used to persist the objects related to
EMPLOYEE table.
import java.util.*;
public Employee() {}
We need to define another POJO class corresponding to ADDRESS entity having address related
fields.
import java.util.*;
public Address() {}
Let us develop our mapping file, which instructs Hibernate how to map the defined classes to the
database tables. The <component> element will be used to define the rule for all the fields
associated with ADDRESS table.
<hibernate-mapping>
<class name = "Employee" table = "EMPLOYEE">
</class>
</hibernate-mapping>
You should save the mapping document in a file with the format <classname>.hbm.xml. We
saved our mapping document in the file Employee.hbm.xml. You are already familiar with most
of the mapping detail, but let us see all the elements of mapping file once again −
Finally, we will create our application class with the main() method to run the application. We
will use this application to save few Employee's records along with their certificates and then we
will apply CRUD operations on those records.
import java.util.*;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
try {
factory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError(ex);
}
try {
tx = session.beginTransaction();
address = new Address(street, city, state, zipcode);
addressID = (Integer) session.save(address);
tx.commit();
} catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
return address;
}
try {
tx = session.beginTransaction();
Employee employee = new Employee(fname, lname, salary, address);
employeeID = (Integer) session.save(employee);
tx.commit();
} catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
return employeeID;
}
try {
tx = session.beginTransaction();
List employees = session.createQuery("FROM Employee").list();
for (Iterator iterator = employees.iterator(); iterator.hasNext();){
Employee employee = (Employee) iterator.next();
System.out.print("First Name: " + employee.getFirstName());
System.out.print(" Last Name: " + employee.getLastName());
System.out.println(" Salary: " + employee.getSalary());
Address add = employee.getAddress();
System.out.println("Address ");
System.out.println("\tStreet: " + add.getStreet());
System.out.println("\tCity: " + add.getCity());
System.out.println("\tState: " + add.getState());
System.out.println("\tZipcode: " + add.getZipcode());
}
tx.commit();
} catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
try {
tx = session.beginTransaction();
Employee employee = (Employee)session.get(Employee.class, EmployeeID);
employee.setSalary( salary );
session.update(employee);
tx.commit();
} catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
}
Compilation and Execution
Here are the steps to compile and run the above mentioned application. Make sure, you have set
PATH and CLASSPATH appropriately before proceeding for the compilation and execution.
$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........
mysql>
Hibernate Inheritance Mapping
In this tutorial, we will discuss how JPA/Hibernate supports Inheritance mapping. We also look
into several inheritance strategies that JPA specification provides.
Relational databases don’t have a straightforward way to map class hierarchies onto database
tables.
To address this, the JPA specification provides several strategies:
Entity inheritance means that we can use polymorphic queries for retrieving all the sub-
class entities when querying for a super-class.
From a database perspective, the @MappedSuperclass inheritance model is invisible since all the
base class properties are simply copied to the database table mapped by the actual entity class.
In the following domain model class hierarchy, a DebitAccount and a CreditAccount share the
same Account base class.
@MappedSuperclass
public static class Account {
@Id
private Long id;
@Entity(name = "DebitAccount")
public static class DebitAccount extends Account {
@Entity(name = "CreditAccount")
public static class CreditAccount extends Account {
}
CREATE TABLE DebitAccount (
id BIGINT NOT NULL ,
balance NUMERIC(19, 2) ,
interestRate NUMERIC(19, 2) ,
owner VARCHAR(255) ,
overdraftFee NUMERIC(19, 2) ,
PRIMARY KEY ( id )
)
SINGLE_TABLE inheritance performs the best in terms of executed SQL statements. However,
you cannot use NOT NULL constraints on the column-level. You can still use triggers and rules
to enforce such constraints, but it’s not as straightforward.
Each subclass in a hierarchy must define a unique discriminator value, which is used to
differentiate between rows belonging to separate subclass types. If this is not specified,
the DTYPE column is used as a discriminator, storing the associated subclass name.
The inheritance strategy is defined on the abstract superclass, using the @Inheritance annotation.
In this example, we used InheritanceType.SINGLE_TABLE. This means all concrete subclasses
will be stored in one table. You can optionally specify a discriminator column name. This
column is registered by the @DiscriminatorColumnif omitted the default DTYPE name is used.
A discriminator column is not required for this mapping strategy. Each subclass must, however,
declare a table column holding the object identifier.
The JOINED table inheritance strategy addresses the data integrity concerns because every
subclass is associated with a different table. Polymorphic queries or @OneToMany base class
associations don’t perform very well with this strategy. However, polymorphic @ManyToOne
associations are fine, and they can provide a lot of value.
package net.javaguides.hibernate.entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
@Entity(name = "Account")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Account {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
package net.javaguides.hibernate.entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
@Entity(name = "Account")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Account {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Hibernate Lifecycle
Here we will learn about Hibernate Lifecycle or in other words, we can say that we will learn
about the lifecycle of the mapped instances of the entity/object classes in hibernate. In Hibernate,
we can either create a new object of an entity and store it into the database, or we can fetch the
existing data of an entity from the database. These entity is connected with the lifecycle and each
object of entity passes through the various stages of the lifecycle.
1. Transient State
2. Persistent State
3. Detached State
4. Removed State
Hibernate Lifecycle
As depicted from the above media one can co-relate how they are plotted in order to plot better
in our mind. Now we will be discussing the states to better interpret hibernate lifecycle. It is as
follows:
The transient state is the first state of an entity object. When we instantiate an object of a POJO
class using the new operator then the object is in the transient state. This object is not connected
with any hibernate session. As it is not connected to any Hibernate Session, So this state is not
connected to any database table. So, if we make any changes in the data of the POJO Class then
the database table is not altered. Transient objects are independent of Hibernate, and they exist in
the heap memory.
There are two layouts in which transient state will occur as follows:
1. When objects are generated by an application but are not connected to any session.
2. The objects are generated by a closed session.
Here, we are creating a new object for the Employee class. Below is the code which shows the
initialization of the Employee object :
//Here, The object arrives in the transient state.
Employee e = new Employee();
e.setId(21);
e.setFirstName("Neha");
e.setMiddleName("Shri");
e.setLastName("Rudra");
Once the object is connected with the Hibernate Session then the object moves into the Persistent
State. So, there are two ways to convert the Transient State to the Persistent State :
1. Using the hibernated session, save the entity object into the database table.
2. Using the hibernated session, load the entity object into the database table.
In this state. each object represents one row in the database table. Therefore, if we make any
changes in the data then hibernate will detect these changes and make changes in the database
table.
session.persist(e);
session.save(e);
session.saveOrUpdate(e);
session.update(e);
session.merge(e);
session.lock(e);
Example:
// Transient State
Employee e = new Employee("Neha Shri Rudra", 21, 180103);
//Persistent State
session.save(e);
State 3: Detached State
For converting an object from Persistent State to Detached State, we either have to close the
session or we have to clear its cache. As the session is closed here or the cache is cleared, then
any changes made to the data will not affect the database table. Whenever needed, the detached
object can be reconnected to a new hibernate session. To reconnect the detached object to a new
hibernate session, we will use the following methods as follows:
merge()
update()
load()
refresh()
save()
update()
session.detach(e);
session.evict(e);
session.clear();
session.close();
Example
// Transient State
Employee e = new Employee("Neha Shri Rudra", 21, 180103);
// Persistent State
session.save(e);
// Detached State
session.close();
Example
// Transient State
Employee e = new Employee();
Session s = sessionfactory.openSession();
e.setId(01);
// Persistent State
session.save(e)
// Removed State
session.delete(e);
A transaction simply represents a unit of work. In such case, if one step fails, the whole
transaction fails (which is termed as atomicity). A transaction can be described by ACID
properties (Atomicity, Consistency, Isolation and Durability).
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).
In hibernate, it is better to rollback the transaction if any exception occurs, so that resources can
be free. Let's see the example of transaction management in hibernate.
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
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:
1. Transaction tx=session.beginTransaction();
2. Query q=session.createQuery("update User set name=:n where id=:i");
3. q.setParameter("n","Udit Kumar");
4. q.setParameter("i",111);
5.
6. int status=q.executeUpdate();
7. System.out.println(status);
8. tx.commit();
You may call avg(), min(), max() etc. aggregate functions by HQL. Let's see some common
examples:
You can use native SQL to express database queries if you want to utilize database-specific
features such as query hints or the CONNECT keyword in Oracle. Hibernate 3.x allows you to
specify handwritten SQL, including stored procedures, for all create, update, delete, and load
operations.
Your application will create a native SQL query from the session with the createSQLQuery()
method on the Session interface −
After you pass a string containing the SQL query to the createSQLQuery() method, you can
associate the SQL result with either an existing Hibernate entity, a join, or a scalar result using
addEntity(), addJoin(), and addScalar() methods respectively.
Scalar Queries
The most basic SQL query is to get a list of scalars (values) from one or more tables. Following
is the syntax for using native SQL for scalar values −
The above queries were all about returning scalar values, basically returning the "raw" values
from the result set. Following is the syntax to get entity objects as a whole from a native sql
query via addEntity().
Following is the syntax to get entity objects from a native sql query via addEntity() and using
named SQL query.
public Employee() {}
<hibernate-mapping>
<class name = "Employee" table = "EMPLOYEE">
</class>
</hibernate-mapping>
Finally, we will create our application class with the main() method to run the application where
we will use Native SQL queries −
import java.util.*;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.SQLQuery;
import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.cfg.Configuration;
try {
factory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError(ex);
}
try {
tx = session.beginTransaction();
Employee employee = new Employee(fname, lname, salary);
employeeID = (Integer) session.save(employee);
tx.commit();
} catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
return employeeID;
}
try {
tx = session.beginTransaction();
String sql = "SELECT first_name, salary FROM EMPLOYEE";
SQLQuery query = session.createSQLQuery(sql);
query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
List data = query.list();
try {
tx = session.beginTransaction();
String sql = "SELECT * FROM EMPLOYEE";
SQLQuery query = session.createSQLQuery(sql);
query.addEntity(Employee.class);
List employees = query.list();
Here are the steps to compile and run the above mentioned application. Make sure, you have set
PATH and CLASSPATH appropriately before proceeding for the compilation and execution.
You would get the following result, and records would be created in the EMPLOYEE table.
$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........
If you check your EMPLOYEE table, it should have the following records −
Hibernate Query Language (HQL) is an object-oriented query language, similar to SQL, but
instead of operating on tables and columns, HQL works with persistent objects and their
properties. HQL queries are translated by Hibernate into conventional SQL queries, which in
turns perform action on database.
Although you can use SQL statements directly with Hibernate using Native SQL, but I would
recommend to use HQL whenever possible to avoid database portability hassles, and to take
advantage of Hibernate's SQL generation and caching strategies.
Keywords like SELECT, FROM, and WHERE, etc., are not case sensitive, but properties like
table and column names are case sensitive in HQL.
FROM Clause
You will use FROM clause if you want to load a complete persistent objects into memory.
Following is the simple syntax of using FROM clause −
If you need to fully qualify a class name in HQL, just specify the package and class name as
follows −
The AS clause can be used to assign aliases to the classes in your HQL queries, especially when
you have the long queries. For instance, our previous simple example would be the following −
The AS keyword is optional and you can also specify the alias directly after the class name, as
follows −
The SELECT clause provides more control over the result set then the from clause. If you want
to obtain few properties of objects instead of the complete object, use the SELECT clause.
Following is the simple syntax of using SELECT clause to get just first_name field of the
Employee object −
It is notable here that Employee.firstName is a property of Employee object rather than a field
of the EMPLOYEE table.
WHERE Clause
If you want to narrow the specific objects that are returned from storage, you use the WHERE
clause. Following is the simple syntax of using WHERE clause −
To sort your HQL query's results, you will need to use the ORDER BY clause. You can order
the results by any property on the objects in the result set either ascending (ASC) or descending
(DESC). Following is the simple syntax of using ORDER BY clause −
String hql = "FROM Employee E WHERE E.id > 10 ORDER BY E.salary DESC";
Query query = session.createQuery(hql);
List results = query.list();
If you wanted to sort by more than one property, you would just add the additional properties to
the end of the order by clause, separated by commas as follows −
This clause lets Hibernate pull information from the database and group it based on a value of an
attribute and, typically, use the result to include an aggregate value. Following is the simple
syntax of using GROUP BY clause −
Hibernate supports named parameters in its HQL queries. This makes writing HQL queries that
accept input from the user easy and you do not have to defend against SQL injection attacks.
Following is the simple syntax of using named parameters −
Bulk updates are new to HQL with Hibernate 3, and delete work differently in Hibernate 3 than
they did in Hibernate 2. The Query interface now contains a method called executeUpdate() for
executing HQL UPDATE or DELETE statements.
The UPDATE clause can be used to update one or more properties of an one or more objects.
Following is the simple syntax of using UPDATE clause −
The DELETE clause can be used to delete one or more objects. Following is the simple syntax
of using DELETE clause −
HQL supports INSERT INTO clause only where records can be inserted from one object to
another object. Following is the simple syntax of using INSERT INTO clause −
HQL supports a range of aggregate methods, similar to SQL. They work the same way in HQL
as in SQL and following is the list of the available functions −
avg(property name)
1
The average of a property's value
count(property name or *)
2
The number of times a property occurs in the results
max(property name)
3
The maximum value of the property values
min(property name)
4
The minimum value of the property values
5 sum(property name)
The sum total of the property values
The distinct keyword only counts the unique values in the row set. The following query will
return only unique count −
Using above two methods together, we can construct a paging component in our web or Swing
application. Following is the example, which you can extend to fetch 10 rows at a time −
HQL has many benefits. Some benefits are – they are database independent, polymorphic queries
supported, and easy to learn for Java programmers.
The Query interface provides object-oriented methods and capabilities for representing and
manipulating HQL queries.
To load a whole persistent object into memory, the FROM clause is used.
The SELECT clause is used when only a few attributes of an object are required rather than the
entire object.
Filtering records is done with the WHERE clause. It’s used to retrieve only the records that meet
a set of criteria.
String hib = "FROM Student S WHERE S.id > 5 ORDER BY S.id DESC";
Query query = session.createQuery(hib);
List results = query.list();
HQL UPDATE Clause
Query setMaxResults(int
Instructs Hibernate to get a specific number of items
max)
Query setFirstResult(int Takes an integer as an argument that represents the first row in
starting_no) your result set, beginning with row 0.
Example
Aggregate Methods
Example 1: average
Example 2: max
Example 3: min
Example 4: count