1. Introduction
Hibernate is an Object-relational mapping
(ORM) tool. Object-relational mapping or ORM is a programming method for
mapping the objects to the relational model where entities/classes are
mapped to tables, instances are mapped to rows and attributes of
instances are mapped to columns of table.
A “virtual object database” is created that can be used from within the programming language.
Hibernate
is a persistence framework which is used to persist data from Java
environment to database. Persistence is a process of storing the data to
some permanent medium and retrieving it back at any point of time even
after the application that had created the data ended.
2. Hibernate Architecture
The
above diagram shows minimal architecture of Hibernate. It creates a
layer between Database and the Application. It loads the configuration
details like Database connection string, entity classes, mappings etc.
Hibernate creates persistent objects which synchronize data between application and database.
The
above diagram shows a comprehensive architecture of Hibernate. In order
to persist data to a database, Hibernate create an instance of entity
class (Java class mapped with database table). This object is called
Transient object as they are not yet associated with the session or not
yet persisted to a database. To persist the object to database, the
instance of SessionFactory interface is created. SessionFactory is a
singleton instance which implements Factory design pattern.
SessionFactory loads hibernate.cfg.xml file (Hibernate configuration
file. More details in following section) and with the help of
TransactionFactory and ConnectionProvider implements all the
configuration settings on a database.
Each database connection in
Hibernate is created by creating an instance of Session interface.
Session represents a single connection with database. Session objects
are created from SessionFactory object.
Hibernate also provides
built-in Transaction APIs which abstracts away the application from
underlying JDBC or JTA transaction. Each transaction represents a single
atomic unit of work. One Session can span through multiple
transactions.
2.1 SessionFactory (org.hibernate.SessionFactory)
A thread-safe, immutable cache of compiled mappings for a single
database. A factory for org.hibernate.Session instances. A client of
org.hibernate.connection.ConnectionProvider. Optionally maintains a
second level cache of data that is reusable between transactions at a
process or cluster level.
2.2 Session (org.hibernate.Session)
A single-threaded, short-lived object representing a conversation
between the application and the persistent store. Wraps a JDBC
java.sql.Connection.
Factory for org.hibernate.Transaction. Maintains a first level cache of
persistent the application’s persistent objects and collections; this
cache is used when navigating the object graph or looking up objects by
identifier.2.3 Persistent objects and collections
Short-lived, single threaded objects containing persistent state and
business function. These can be ordinary JavaBeans/POJOs. They are
associated with exactly one
org.hibernate.Session. Once the
org.hibernate.Session is closed, they will be detached and free to use
in any application layer (for example, directly as data transfer objects
to and from presentation).2.4 Transient and detached objects and collections
Instances of persistent classes that are not currently associated with a
org.hibernate.Session. They may have been instantiated by the
application and not yet persisted, or they may have been instantiated by
a closed org.hibernate.Session.
2.5 Transaction (org.hibernate.Transaction)
(Optional) A single-threaded, short-lived object used by the
application to specify atomic units of work. It abstracts the
application from the underlying JDBC, JTA or CORBA transaction. A
org.hibernate.Session might span several org.hibernate.Transactions in
some cases. However, transaction demarcation, either using the
underlying API or org.hibernate.Transaction, is never optional.
2.6 ConnectionProvider (org.hibernate.connection.ConnectionProvider)
(Optional) A factory for, and pool of, JDBC connections. It abstracts
the application from underlying javax.sql.DataSource or
java.sql.DriverManager. It is not exposed to application, but it can be
extended and/or implemented by the developer.
2.7 TransactionFactory (org.hibernate.TransactionFactory)
(Optional) A factory for org.hibernate.Transaction instances. It is not
exposed to the application, but it can be extended and/or implemented
by the developer.
3. Hibernate Configuration
Hibernate configuration is managed by an instance of
org.hibernate.cfg.Configuration.
An instance of org.hibernate.cfg.Configuration represents an entire set
of mappings of an application’s Java types to an SQL database. The
org.hibernate.cfg.Configuration is used to build an immutable org.hibernate.SessionFactory. The mappings are compiled from various XML mapping files or from Java 5 Annotations.
Hibernate provides following types of configurations
- hibernate.cfg.xml – A standard XML file which contains hibernate configuration and which resides in root of application’s CLASSPATH
- hibernate.properties – A Java compliant property file which holds key value pair for different hibernate configuration strings.
- Programmatic configuration – This is the manual approach. The configuration can be defined in Java class.
3.1 hibernate.cfg.xml
This
is an alternate way of configuring hibernate. The hibernate.cfg.xml
file is a standard XML file which contains all the configuration
parameters like database connection, class mappings etc. This file needs
to be placed root of CLASSPATH of application.
Below is the sample hibernate.cfg.xml file:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| <?xml version='1.0' encoding='utf-8'?><!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"><hibernate-configuration> <!-- a SessionFactory instance listed as /jndi/name --> <session-factory name="java:hibernate/SessionFactory"> <!-- properties --> <property name="connection.datasource">java:/comp/env/jdbc/MyEmployeeDB</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="show_sql">false</property> <property name="transaction.factory_class"> org.hibernate.transaction.JTATransactionFactory </property> <property name="jta.UserTransaction">java:comp/UserTransaction</property> <!-- mapping files --> <mapping resource="net/viralpatel/hibernate/Employee.hbm.xml"/> <mapping resource="net/viralpatel/hibernate/Department.hbm.xml"/> <!-- cache settings --> <class-cache class="net.viralpatel.hibernate.Employee" usage="read-write"/> <class-cache class="net.viralpatel.hibernate.Department" usage="read-only"/> <collection-cache collection="net.viralpatel.hibernate.Department.employees" usage="read-write"/> </session-factory></hibernate-configuration> |
Once
the hibernate.cfg.xml file is created and placed in root of
application’s CLASSPATH, the same can be loaded in Hibernate using
following API.
1
| SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(); |
This above code will load default hibernate.cfg.xml file and all the configuration mentioned in it.
In
case you want to override default naming convention and want to have
your own configuration file like “employeedb.cfg.xml”, following API can
be used:
1
2
3
| SessionFactory sf = new Configuration() .configure("employeedb.cfg.xml") .buildSessionFactory(); |
Note: Both hibernate.cfg.xml and hibernate.properties files can be provided simultaneously in an application. In this case hibernate.cfg.xml gets precedence over hibernate.properties.
3.2 hibernate.properties
This
is the easiest way to get started with Hibernate. Create a file
hibernate.properties and place it in root of your applications
CLASSPATH.
Below is the sample hibernate.properties file:
01
02
03
04
05
06
07
08
09
10
| hibernate.connection.driver_class=com.mysql.jdbc.Driverhibernate.connection.url= jdbc:mysql://localhost:3306/employeehibernate.connection.username=roothibernate.connection.password=swordfishhibernate.connection.pool_size=1hibernate.transaction.factory_class = \ org.hibernate.transaction.JTATransactionFactoryhibernate.transaction.manager_lookup_class = \ org.hibernate.transaction.JBossTransactionManagerLookuphibernate.dialect = org.hibernate.dialect.MySQLDialect |
For detail description of Configuration parameters, refer this article Hibernate configuration properties.
3.3 Programmatic configuration
We
can obtain a org.hibernate.cfg.Configuration instance by instantiating
it directly and specifying XML mapping documents. If the mapping files
are in the classpath, use addResource(). For example:
1
2
3
| Configuration cfg = new Configuration() .addResource("Employee.hbm.xml") .addResource("Department.hbm.xml"); |
An alternative way is to specify the mapped class and allow Hibernate to find the mapping document for you:
1
2
3
| Configuration cfg = new Configuration() .addClass(net.viralpatel.hibernate.Employee.class) .addClass(net.viralpatel.hibernate.Department.class); |
Hibernate
will then search for mapping files named
/net/viralpatel/hibernate/Employee.hbm.xml and
/net/viralpatel/hibernate/Department.hbm.xml in the classpath. This
approach eliminates any hardcoded filenames.
A org.hibernate.cfg.Configuration also allows you to specify configuration properties. For example:
1
2
3
4
5
6
| Configuration cfg = new Configuration() .addClass(net.viralpatel.hibernate.Employee.class) .addClass(net.viralpatel.hibernate.Department.class) .setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect") .setProperty("hibernate.connection.datasource", "java:comp/env/jdbc/test") .setProperty("hibernate.order_updates", "true"); |
4. Building a SessionFactory
Once
the instance of org.hibernate.cfg.Configuration is created using any of
the above method, the singleton instance of SessionFactory can be
created as follow:
1
| SessionFactory sessions = cfg.buildSessionFactory(); |
Hibernate
does allow your application to instantiate more than one
org.hibernate.SessionFactory. This is useful if you are using more than
one database.
5. Getting Session instance
As noted above,
Session represents a communication channel between database and
application. Each session represents a factory of transactions. Session
can be created from SessionFactory as follows:
1
| Session session = sessions.openSession(); // get a new Session |
Thus,
in this article we saw an overview of Hibernate ORM and its
architecture. Also we noted its different components like
SessionFactory, TransactionFactory, Session etc and APIs to instantiate
these objects in your application.