Hibernate
Last updated
Last updated
A Complete solution to the problem of managing persistence in Java.
An ORM tool (Object Relational Mapping) used mainly in data access layer or DAO layer.
JPA (Java Persistence API) specification implementor and is an object oriented abstraction.
It is an automatic & transparent persistence framework to store & retrieve data from database.
Open Source Java based framework founded by Gavin King in 2001, which was hosted on hibernate.org. Currently hosted on sourceforge.net.
Java Persistence API (JPA) compliant current version of hibernate is Hibernate 5.x
, and latest release is 6.x
.
Other popular ORM Frameworks are EclipseLink, iBATIS, Kodo etc.
JPA is a standard part of J2EE specification whose vendor is J2EE (sun).
Implementation classes of these specification is hibernate-core JARs (implementor of JPA).
It mediates the applications interaction with a relational database, so that the developer can concentrate on the business problem at hand.
J2EE developer does not have to use JDBC API & manage data persistence at RDBMS level.
No need to go to Table/Query/Column level.
One has to bootstrap Hibernate framework, create transient i.e., not yet persistent POJOs & then rely entirely on Hibernate framework to manage persistence.
There is huge mismatch between Object & Relational Database world, formally referred as Object-Relational Impedance Mismatch
(sometimes called the paradigm mismatch
)
Important Mismatch Points
Granularity
Sub Types or inheritance and polymorphism
Identity
Associations
Data Navigation
Cost of Mismatch
SQL queries in Java code
Iterating through ResultSet & mapping it to POJOs or entities.
SQLException handling.
Transaction management
Caching
Connection pooling
Boiler plate code
Hibernate 4.x
and above is a JPA compliant Java persistence API which is a part of J2EE specifications.
It is fully JPA compliant, however it also has additional services/annotations specific to Hibernate.
Developer MUST add hibernate JARs while deploying application on web server.
Developer need not add JPA provider JARs, while working on application server.
Transparent persistence provider. (As POJOs or Entities are not bound to any Persistence API, its written completely independent of Persistence Provider.)
Fully supports OOP features such as association, inheritance & polymorphism
It can persist object graphs, consisting of associative objects.
Caches data which is fetched repeatedly (via L1 & L2 cache) and thus reducing DB traffic.
L1 cache, sits at session level which is a built in.
L2 cache which is pluggable, sits at global session factory level.(More on caching at the end).
Supports lazy loading and thus increases DB performance.
Lazy fetching
The associated object or collection is fetched lazily, when its first accessed.
This results in a new request to the database (unless the associated object is cached).
Eager fetching
The associated object or collection is fetched together with the owning object, using an SQL outer join, and no further database request is required.
Supports objectified version of SQL i., HQL
works on objects & properties.
Hibernate usually obtains exactly the right lock level automatically. Hence, developer need not worry about applying Read/Write lock.
Hibernate uses runtime reflection to determine the persistent properties of a class.
The objects to be persisted (called as POJO or Entity) are defined in a mapping document or marked with annotations. Either these HBM XML
(hibernate mapping) configuration or annotations serves to describe the persistent fields and associations, as well as any subclasses or proxies of the persistent object.
The mapping documents or annotations are compiled at application startup time and provide the framework with necessary information for a persistent class.
What is Hibernate configuration?
An instance of Hibernate configuration allows the application to specify properties and mapping documents to be used at the framework start-up.
The configuration is an initialization-time object.
SessionFactory
is created from the compiled collection of mapping documents. The SessionFactory
provides the mechanism for managing persistent classes through the Session
interface.
A web application or Java SE application will create a single configuration, build a single instance of SessionFactory and then instantiate multiple session object in threads servicing client requests.
SessionFactory
is immutable and does not reflect any changes done later to the configuration.
The Session
class provides the interface between the persistent data store and the application. The Session
interface wraps a JDBC connection, which can be user-managed or controlled by Hibernate.
It is a factory (provider) of session objects.
We use sessionfactory object to create session object
It is a heavy weight object, therefore it has to be created only once for an application typically at application start up time one per DB per web application.
Its immutable i.e Once Session Factory object is created, changes made to hibernate.cfg.xml
will not be auto reflected in SF.
A code snippet to configure a session factory can be seen here.
Represents a wrapper around pooled out jdbc connection.
Session object is persistance manager for the hibernate application.
Session object is the abstraction of hibernate engine for the Hibernate application.
Session object provides methods to perform CRUD operations.
save()
Inserting the record
get()
/load()
Retrieving the record
update()
Updating the record
delete()
Deleting the record
Configuration object is used to create the SessionFactory
object.
Object Oriented Representation of Hibernate configuration file and mapping files (or annotations) is nothing but Configuration object.
When we call configure()
method on configuration object, hibernate configuration file is read (hibernate.cfg.xml
, which is a default name from run time classpath) and mapping files (or resources) are loaded in the memory.
A sample configuration xml for MySQL is here.
Java applications should use connection pools because,
Acquiring a new connection is too expensive.
Maintaining many idle connections is expensive.
Creating prepared statements is expensive.
Hibernate provides basic or primitive connection pool which is useful only for classroom testing.
Replace it by 3rd party vendor supplied connection pools (eg Apache or C3P0. Hikari Connection Pool is used in spring boot) for production grade applications.
An Hibernate Session is a set of managed entity instances that exist in a particular data store.
It manages an Entity Instances Life Cycle.
You manage entity instances (or POJOs) by invoking operations on the entity/POJO using EntityManager
/Session
instance.
Entity instances are in one of four states (2 important aspects of entity is that, entity associates with the hibernate session & synchronizes its state with the underlying DB.)
transient
(new)
New entity instances have no persistent identity and are not yet associated with a hibernate session (transient)
persistent
(managed)
Managed entity instances have a persistent identity and are associated with a hibernate session. (persisted via save() or saveOrUpdate()) Changes to database will be done once the transaction is commited.
detached
Detached entity instances have a persistent identity and are not currently associated with a persistence context/Hibernate session.
removed
Removed entity instances have a persistent identity, are associated with a persistent context and are scheduled for removal from the data store (removed via session.delete(obj)
).
If you have User registeration system then you have a business rule that user email must be distinct.
So if you want to make this as a primary key then user will have to supply this during registration.
This is called as natural key. Since its value will be user supplied, you cannot tell hibernate to generate it for you.
i.e cant use @GeneratedValue
annotation at all.
Where, as if you say I will reserve user id only for mapping purposes (similar to serial number), it need not come from user at all & can definitely be auto generate by hibernate for you and hence this is your surrogate key & can then use @GeneratedValue
annotation which will use native database policy.
Read more about surrogate key here.
While working with Hibernate web applications we will face so many problems in its performance due to database traffic. That too when the database traffic is very high. Actually, hibernate is well known just because of its high performance only. So some techniques are used to make sure to maintain its performance.
Caching is the best technique used to reduce traffic to the database and solve traffic problem.
The performance of Hibernate web applications is improved using caching by optimizing the database calls.
The cache actually stores the data already loaded from the database, so that the traffic between our application and the database will be reduced when the application want to access that data again.
At maximum, the application will work with the data in the cache only.
Whenever some another data is needed which is not present in cache, the database will be accessed.
Because the time needed to access the database is more compared with the time needed to access the cache by using cache, obviously the access time and traffic will be reduced between the application and the database.
Here the cache stores only the data related to current running application.
In order to do that, the cache must be cleared from time to time whenever the applications are changing.