0% found this document useful (0 votes)
102 views

Hibernate Questions and Answers

The document discusses Hibernate, an ORM framework for Java that maps objects to relational database tables. It provides 3 key benefits: 1) It eliminates boilerplate JDBC code and manages resources, allowing a focus on business logic. 2) It supports both XML and JPA annotations for implementation-independent code. 3) Its query language, HQL, is object-oriented like SQL but understands OOP concepts. The document also compares Hibernate to JDBC, noting Hibernate's automatic transaction management, exception handling, and table creation abilities. Finally, it outlines important Hibernate interfaces like SessionFactory and Session, and compares the get(), load(), save(), persist(), and saveOrUpdate() methods

Uploaded by

Vidhi Gupta
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
102 views

Hibernate Questions and Answers

The document discusses Hibernate, an ORM framework for Java that maps objects to relational database tables. It provides 3 key benefits: 1) It eliminates boilerplate JDBC code and manages resources, allowing a focus on business logic. 2) It supports both XML and JPA annotations for implementation-independent code. 3) Its query language, HQL, is object-oriented like SQL but understands OOP concepts. The document also compares Hibernate to JDBC, noting Hibernate's automatic transaction management, exception handling, and table creation abilities. Finally, it outlines important Hibernate interfaces like SessionFactory and Session, and compares the get(), load(), save(), persist(), and saveOrUpdate() methods

Uploaded by

Vidhi Gupta
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 22

Q) What is Hibernate Framework?

A) Object-relational mapping or ORM is the programming technique to map application domain


model objects to the relational database tables. Hibernate is java based ORM tool that provides
framework for mapping application domain objects to the relational database tables and vice versa.
Hibernate provides reference implementation of Java Persistence API, that makes it a great choice
as ORM tool with benefits of loose coupling. We can use Hibernate persistence API for CRUD
operations. Hibernate framework provide option to map plain old java objects to traditional
database tables with the use of JPA annotations as well as XML based configuration. Similarly
hibernate configurations are flexible and can be done from XML configuration file as well as
programmatically.

Q).What is Java Persistence API (JPA)?


A) Java Persistence API (JPA) provides specification for managing the relational data in applications.
Current JPA version 2.1 was started in July 2011 as JSR 338. JPA 2.1 was approved as final on 22 May
2013. JPA specifications are defined with annotations in javax.persistence package. Using JPA
annotation helps us in writing implementation independent code.

Q) What are the important benefits of using Hibernate Framework?


Some of the important benefits of using hibernate framework are:
1. Hibernate eliminates all the boiler-plate code that comes with JDBC and takes care of managing
resources, so we can focus on business logic.
2. Hibernate framework provides support for XML as well as JPA annotations, that makes our code
implementation independent.
3. Hibernate provides a powerful query language (HQL) that is similar to SQL. However, HQL is fully
object-oriented and understands concepts like inheritance, polymorphism and association.
4. Hibernate is an open source project from Red Hat Community and used worldwide. This makes it
a better choice than others because learning curve is small and there are tons of online
documentations and help is easily available in forums.
5. Hibernate is easy to integrate with other Java EE frameworks, it’s so popular that Spring
Framework provides built-in support for integrating hibernate with Spring applications.
6. Hibernate supports lazy initialization using proxy objects and perform actual database queries
only when it’s required.
7. Hibernate cache helps us in getting better performance.
8. For database vendor specific feature, hibernate is suitable because we can also execute native
SQL queries.

Q) What are the advantages of Hibernate over JDBC?


Some of the important advantages of Hibernate framework over JDBC are:
1. Hibernate implicitly provides transaction management, in fact most of the queries can’t be
executed outside transaction. In JDBC API, we need to write code for transaction management
using commit and rollback
2. JDBC API throws SQLException that is a checked exception, so we need to write a lot of try-catch
block code. Most of the times it’s redundant in every JDBC call and used for transaction
management. Hibernate wraps JDBC exceptions and throw JDBCException or
HibernateException un-checked exception, so we don’t need to write code to handle it.
Hibernate built-in transaction management removes the usage of try-catch blocks.
3. Hibernate provide option through which we can create database tables too, for JDBC tables
must exist in the database.
4. Hibernate configuration helps us in using JDBC like connection as well as JNDI Data Source for
connection pool. This is very important feature in enterprise application and completely missing
in JDBC API.

<<Q) Name some important interfaces of Hibernate framework?


A) Some of the important interfaces of Hibernate framework are:
SessionFactory (org.hibernate.SessionFactory): SessionFactory is an immutable thread-safe cache
of compiled mappings for a single database. We need to initialize SessionFactory once and then we
can cache and reuse it. SessionFactory instance is used to get the Session objects for database
operations.
Session (org.hibernate.Session): Session is a single-threaded, short-lived object representing a
conversation between the application and the persistent store. It wraps JDBC java.sql.Connection
and works as a factory for org.hibernate.Transaction. We should open session only when it’s
required and close it as soon as we are done using it. Session object is the interface between java
application codes and hibernate framework and provide methods for CRUD operations.
Transaction (org.hibernate.Transaction): Transaction is a single-threaded, short-lived object used
by the application to specify atomic units of work. It abstracts the application from the underlying
JDBC or JTA transaction. An org.hibernate.Session might span multiple org.hibernate.Transaction in
some cases.

<<Q) get() vs load() in Hibernate


A) Difference between get and load method
1. Behavior when Object is not found in Session Cache
get() method of Hibernate Session class returns null if object is not found in cache as well as on
database while load() method throws ObjectNotFoundException if object is not found on cache as
well as on database but never return null.
2. Database hit
get() method always hit database while load() method may not always hit the database, depending
upon which method is called.
3. Proxy
get() method never returns a proxy, it either returns null or fully initialized Object,
while load() method may return proxy, which is the object with ID but without initializing other
properties, which is lazily initialized. If you are just using returned object for creating relationship
and only need Id then load() is the way to go.
4. Performance
get method will return a completely initialized object if  Object is not on the cache but exists
on Database, which may involve multiple round-trips to database based upon object relational
mappings while load() method of Hibernate can return a proxy which can be initialized on demand
(lazy initialization) when a non-identifier method is accessed. Due to above reason use of load
method will result in slightly better performance, but there is a caveat that proxy object will
throw ObjectNotFoundException later if corresponding row doesn’t exists in database, instead of
failing immediately so not a fail fast behavior.
5. load() method exists prior to get method which is added on user request.
When to use Session get() and load() in Hibernate
1. Use get() method to determine if an instance exists or not because it can return null if instance
doesn’t exists in cache and database and use load method to retrieve instance only if you think that
instance should exists and non-availability is an error condition.
2.  get() method could suffer performance penalty if only identifier method like getId()  is accessed.
So consider using load method if your code doesn't access any method other than identifier or you
are OK with lazy Initialization of object, if persistent object is not in Session Cache because load() can
return proxy.

How to call get records in Hibernate using get and load method
If you look at below code , there is not much difference on calling get() and load() method, though
both are overloaded now and can accept few more parameters but the primary methods looks
exactly identical. It’s their behavior which makes them different.
//Example of calling get method of Hiberante Session class
Session session = SessionFactory.getCurrentSession();
Employee Employee = (Employee) session.get(Employee.class, EmployeeID);

//Example of calling load method of Hiberante Session


Session session = SessionFactory.getCurrentSession();
Employee Employee = (Employee) session.load(Employee.class, EmployeeID);

Q) Difference between save(), persist() and saveOrUpdate() methods in Hibernate?


All three methods i.e. save(), saveOrUpdate() and persist() is used to save objects into database, but
has subtle differences e.g. save() can only INSERT records but saveOrUpdate() can either INSERT or
UPDATE records. Also, return type of save() is a Serializable object, while return type of persist()
method is void.
Difference between save and saveOrUpdate in Hibernate
Main difference between save and saveOrUpdate method is that save() generates a new identifier
and INSERT record into database while saveOrUpdate can either INSERT or UPDATE based upon
existence of record. Clearly saveOrUpdate() is more flexible in terms of use but it involves an extra
processing to find out whether record already exists in table or not. In summary  save() method
saves records into database by INSERT SQL query, Generates a new identifier and return
the Serializable identifier back. On the other hand saveOrUpdate() method either INSERT or UPDATE
based upon existence of object in database. If persistence object already exists in database then
UPDATE SQL will execute and if there is no corresponding object in database than INSERT will run.
Difference between save and persist method in Hibernate
1) First difference between save and persist is there return type. Similar to save method persist
also INSERT records into database but return type of persist is void while return type of save
is Serializable object.  
2) Another difference between persist and save is that both methods make a transient instance
persistent. However, persist() method doesn't guarantee that the identifier value will be
assigned to the persistent instance immediately; the assignment might happen at flush time.
3) persist() method guarantees that it will not execute an INSERT statement if it is called outside
of transaction boundaries, save() method does not guarantee the same, it returns an identifier,
and if an INSERT has to be executed to get the identifier (e.g. "identity" generator), this INSERT
happens immediately, no matter if you are inside or outside of a transaction.
4) Fourth difference between save and persist method in Hibernate is related to previous
difference on save vs persist. Because of its above behavior of persist method outside
transaction boundary, its useful in long-running conversations with an extended Session context.
On the other hand save method is not good in a long-running conversation with an extended
Session context.

Q) What is First and Second Level Cache in Hibernate


A) Hibernate provides caching at many levels e.g. first level cache at Session level, second level
cache at the SessionFactory level, and query cache to cache frequently executed SQL queries.
The first level cache minimizes database access for the same object. For example, if you call
the get() method to access Employee object with id = 1 from one session, it will go to the database
and load the object into memory, but it will also cache the object in the first level cache. When you
will call the get() method again for the same object from the same session, even after doing some
updates on the object, it will return the object from the cache without accessing the database. This
session level cache greatly improves the performance of Java application by minimizing database
roundtrips and executing less number of queries. For example, if an object is modified several times
within the same transaction, then Hibernate will only generate one SQL UPDATE statement at the
end of the transaction, containing all the modification. But, since this cache is associated with
the Session object, which is a short-lived object in Hibernate, as soon as you close the session, all
the information held in the cache is lost. So, if you try to load the same object using
the get() method, Hibernate will go to the database again and fetch the record. This poses
significant performance challenge in an application where multiple sessions are used for this
Hibernate provides another application level cache, known as second level cache, which can be
shared among multiple sessions. This means a request for the same object will not go to the
database even if it is executed from multiple sessions, provided object is present in the second level
cache. The second level cache is maintained at the SessionFactory level, which is used to open
sessions, hence every session is linked to SessionFactory. This cache is opposite to first level cache
which is by default enabled in Hibernate, this one is by default disabled and you need to configure
the second level cache in Hibernate configuration file to enable it. The second level cache is
provided with the help of caching providers e.g. EhCache and OSCache. If you look at the cache
package in Hibernate, you can see the implementation of Caching related interfaces by these
providers. Depending upon which cache you want to use, you can configure them in the Hibernate
Configuration file. Once configured, every request for an object will go to the second level cache if it
is not found in the first level cache. It won't hit the database without consulting second level cache,
which means improved performance.
Difference between First and Second Level Cache in Hibernate
Scope
First level cache is associated with Session Object, while the Second level cache is associated with
the SessionFactory object. This means first level cache's scope is limited to session level while
second level cache's scope is at the application level. Since Session object is created on demand
from the SessionFactory and it's destroyed once the session is closed, the same query if run from
two different sessions will hit the database twice if the second level cache is not configured. On the
other hand, second level cache remains available throughout the application's life-cycle.
Configuration
First level cache is by default enabled in Hibernate, while the second level cache is optional. If you
need it then you need to explicitly enable the second level cache on Hibernate configuration file i.e.
the hibernate.cfg.xml file.
You can use the hibernate.cache.provider_class and hibernate.cache.use_second_level_cache
properties to enable the second level cache in Hibernate. The first one is the name of the class
which implements Second level cache and could be different, depending upon which cache you use
e.g. EhCache or OSCache.
By default, hibernate.cache.provider_class is set to org.hibernate.cache.NoCacheProvider class,
which means the second level cache is disabled. You can enable it by setting something
like org.hibernate.cache.EhCacheProvider if you want to use EhCache as the second level cache.
Here is a sample configuration to configure Second level cache with EhCache:

<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>

Availability
First level cache is available only until the session is open, once the session is closed; the first level
cache is destroyed. On the other hand, second level cache is available through the application's life-
cycle; it is only destroyed and recreated when you restart your application.
Order
If an entity or object is loaded by calling the get() method then Hibernate first checked the first level
cache, if it doesn't found the object then it goes to the second level cache if configured. If the object
is not found then it finally goes to the database and returns the object, if there is no corresponding
row in the table then it return null. When an object is loaded from the database is put on both
second level and first level cache, so that other session who requests the same object can now get it
from the second level cache.
In case if the object is not found in the first level cache but found in the second level cache because
some other sessions have loaded the object before then it is not only returned from first level cache
but also cached at first level cache, so that next time if your code request the same object, it should
be returned from 1st level cache rather than going to the 2nd level cache.
When an object is pass to save(), update(), or saveOrUpdate() method and retrieved by load(), get(),
list(), iterate(), or scroll() method, that object is added to the internal cache of the Session and when
the flush() is subsequently called, the state of the object is synchronized with the database.
Second level cache can also be configured on a per-class and per-collection basis, which means it,
can cache a class or a collection. You can use class-cache and collection-cache elements
in hibernate.cfg.xml to specify which class or collection to cache at 2nd level cache. You should
remember that second level cache by default doesn't cache any entity until you configure it.
You can also use JPA Annotation @Cacheable to specify which entity is cacheable and Hibernate
annoation @Cache to specify caching strategy e.g. CacheConcurrencyStrategies like READ_WRITE or
READ_ONLY to tell Hibernate how the second level cache should behave.

Q) What is query cache in Hibernate?


Query Cache actually stores result of SQL query for future calls. Query cache can be used along with
second level cache for improved performance. Hibernate support various open source caching
solution to implement Query cache e.g. EhCache. Hibernate implements a cache region for queries
result set that integrates closely with the hibernate second-level cache. This is an optional feature
and requires additional steps in code. This is only useful for queries that are run frequently with the
same parameters. First of all we need to configure below property in hibernate configuration file.

<property name="hibernate.cache.use_query_cache">true</property>

And in code, we need to use setCacheable(true) method of Query, quick example looks like below.

Query query = session.createQuery("from Employee");


query.setCacheable(true);
query.setCacheRegion("ALL_EMP");

Q) Why JPA Entity or Hibernate Persistence Class should not be final?


A) Use of proxies is the core feature of Hibernate for implementing key performance features
e.g. lazy loading and lazy associations fetching. In order to use a proxy in place of real class, your
hibernate persistence class must be either non-final or the implementation of an interface that
declares all of the public methods. Why? because you cannot extend a final class in Java, and to
stand up as a proxy, proxy class must satisfy the IS-A relation, which comes either by extending a
class using "extends", or implementing an interface using "implements". By the way, it doesn't mean
that you cannot persist your final entity class, you can, but this will limit Hibernate's ability to use
proxies for lazy association fetching, which will affect the performance of Java application.
Hibernate framework makes extensive use of proxy e.g. it uses proxies when you call the load()
method, it also uses proxies for lazily loading associations and collections of an entity class. Not
using proxies is bad for performance because more SQL than you'd like may be fired against the
database, which also increases database round-trips. You can verify this by printing class name of
your entity class and look at Hibernate query logs, as shown in the following example:
Let's say you load your entity class e.g. a Book, an Employee or a Customer using the load()
method and further print name of class, you will see a different name e.g.

Customer customer = (Customer) session.load(Customer.class, 1L);


logger.info("Name of Customer Entity class : " + customer.getClass());

will print "sample.hibernate.Customer_$$_javassist_0" which is a JavaAssist generated the proxy.

You will not see any select query fired because the load is lazy and it will not load object until you
call any method other than the getId(), Now, if you make the class final and reprint the name of the
class, you will see the actual name of the class as "Customer". You will also see the select queries
fired by hibernate to initialize the object.
You should now understand how costly it can be if you are creating too many objects and only
accessing their getId() method, as it will result in lots of database calls. That's why you should not
make your JPA Entity or Hibernate persistence class final in Java.
Important points to about Entity class, Final, and Proxying
1) Hibernate doesn't create a proxy for final class, instead, they use the real class, but Hibernate
does create a proxy for a non-final class with final methods.
2) Since in Java, you cannot override final methods, the code inside final method remains
unchanged in the proxy class. Which means, if you call a final method on a proxy, it will simply
delegate the call to the super class method? You should be careful not to modify state on final
method because calling them on proxy has a good chance of throwing NullPointerException, as the
object was likely to be not initialized at that point.
In short, avoid final methods on hibernate entity class, until you know what you are doing.
Hibernate reference also stress this point "You should avoid declaring public final methods as this
will again limit the ability to generate proxies from this class. If you want to use a class with public
final methods, you must explicitly disable proxying".
3) As per Hibernate documentation, if  you're going to make a class final you should explicitly disable
proxy generation by adding @Proxy(lazy=false), but I haven't noticed any differences between
doing that and just making the class final.
4) You should also disable proxy generation if you're going to make any public methods final in
persistent class, as hibernate will not be able to override them to put its smart code which triggers
lazy loading etc.
5) If you really want to make the Hibernate entity classes final then you can do it by having your
entity implement an interface that declares all of its public methods. This will still allow Hibernate to
use proxies.
In short, making a JPA Entity or Hibernate Persistence class final, limits the ability of Hibernate to
use Proxies, which in turn prevent Hibernate from applying some performance optimizations.
Without proxies, your application loses lazy loading, and lazy association fetching will issue more
SQL queries and make more database roundtrip, which will cost performance.
The only way to make a Hibernate entity class final without losing lazy behavior is to use interface
and define all public methods of persistence class there, this will still allow Hibernate to use a proxy
in place of real class.

<Q) What is named SQL query in Hibernate?


Named queries are SQL queries which are defined in mapping document using <sql-query> tag and
called using Session.getNamedQuery() method. Named query allows you to refer a particular query
by the name you provided, by the way you can define named query in hibernate either by using
annotations or xml mapping file, as I said above. @NameQuery is used to define single named query
and @NameQueries is used to define multiple named query in hibernate.

<<Q) What is SessionFactory in Hibernate? Is SessionFactory thread-safe?


SessionFactory as name suggest is a factory to create hibernate Session objects. SessionFactory is
often built during start-up and used by application code to get session object. SessionFactory is
responsible to read hibernate configuration parameters and connect to the database and provide
Session objects. Usually an application has a single SessionFactory instance and threads servicing
client requests obtain Session instances from this factory.
Hibernate SessionFactory is thread safe?
Internal state of SessionFactory is immutable, so it’s thread safe. Multiple threads can access it
simultaneously to get Session instances. Usually a Java JEE application has just one SessionFactory,
and individual threads, which are servicing client’s request obtain hibernate Session instances from
this factory, that’s why any implementation of SessionFactory interface must be thread-safe. The
internal state of a SessionFactory is immutable. Once it is created this internal state is set. This
internal state includes all of the metadata about Object/Relational Mapping. SessionFactory also
provide methods to get the Class metadata and Statistics instance to get the stats of query
executions, second level cache details etc. is Immutable and cannot be changed once created.

<Q) What is Hibernate Session and how to get it?


A) Hibernate Session is the interface between java application layer and hibernate. This is the core
interface used to perform database operations. Lifecycle of a session is bound by the beginning and
end of a transaction. Session provide methods to perform create, read, update and delete
operations for a persistent object. We can execute HQL queries, SQL native queries and create
criteria using Session object.
Hibernate Session is thread safe?
Hibernate Session object is not thread safe, every thread should get its own session instance and
close it after its work is finished. Though Session obtains database connection lazily it's good to close
session as soon as you are done with it.

Q) What is difference between openSession and getCurrentSession?


A) Hibernate SessionFactory getCurrentSession() method returns the session bound to the context.
But for this to work, we need to configure it in hibernate configuration file. Since this session object
belongs to the hibernate context, we don’t need to close it. Once the session factory is closed, this
session object gets closed.
<property name="hibernate.current_session_context_class">thread</property>
Hibernate SessionFactory openSession() method always opens a new session. We should close this
session object once we are done with all the database operations. We should open a new session
for each request in multi-threaded environment.
There is another method openStatelessSession() that returns stateless session, for more details with
examples please read Hibernate openSession vs getCurrentSession.

Q) What is use of Hibernate Session merge() call?


Hibernate merge can be used to update existing values, however this method create a copy from
the passed entity object and return it. The returned object is part of persistent context and tracked
for any changes, passed object is not tracked. For example program, read Hibernate merge.

<Q) What is difference between sorted and ordered collection in hibernate?


A sorted collection is sorted in memory by using Java Comparator, while an ordered collection uses
database's order by clause for ordering. For large data set it's better to use ordered collection to
avoid any OutOfMemoryError in Java, by trying to sort them in memory.

<Q) What are different states of an entity bean?


An entity bean instance can exist is one of the three states.
Transient: When an object is never persisted or associated with any session, it’s in transient state.
Transient instances may be made persistent by calling save(), persist() or saveOrUpdate(). Persistent
instances may be made transient by calling delete().
Persistent: When an object is associated with a unique session, it’s in persistent state. Any instance
returned by a get() or load() method is persistent. Any change in this object will reflect in database
based upon your flush strategy i.e. automatic flush whenever any property of object change or
explicit flushing by calling Session.flush() method.
Detached: When an object is previously persistent but not associated with any session, it’s in
detached state. Detached instances may be made persistent by calling update(), saveOrUpdate(),
lock() or replicate(). The state of a transient or detached instance may also be made persistent as a
new persistent instance by calling merge().

Q) Difference between session.update() and session.lock() in Hibernate ?


Both of these methods and saveOrUpdate() method are intended for reattaching a detached object.
The session.lock() method simply reattaches the object to the session without checking or updating
the database on the assumption that the database in sync with the detached object.  It is the best
practice to use either session.update(..) or session.saveOrUpdate(). Use session.lock() only if you are
absolutely sure that the detached object is in sync with your database or if it does not matter
because you will be overwriting all the columns that would have changed later on within the same
transaction. 

Q) Why it's important to provide no argument constructor in Hibernate Entities?


Every Hibernate Entity class must contain a no argument constructor, because Hibernate framework
creates instance of them using Reflection API, by calling Class.newInstance() method. This method
will throw InstantiationException if it doesn't found a no argument constructor inside Entity class.

Q) Can we make a Hibernate Entity Class final?


Yes, you can make a Hibernate Entity class final, but that's not a good practice. Since Hibernate uses
proxy pattern for performance improvement in case of lazy association, by making an entity final,
Hibernate will no longer be able to use proxy, because Java doesn't allow extension of final class,
thus limiting your performance improvement options. Though, you can avoid this penalty, if your
persistent class is an implementation of interface, which declares all public methods defined in
Entity class.

Q) What is hibernate configuration file?


Hibernate configuration file contains database specific configurations and used to initialize
SessionFactory. We provide database credentials or JNDI resource information in the hibernate
configuration xml file. Some other important parts of hibernate configuration file is Dialect
information, so that hibernate knows the database type and mapping file or class details.

Q) What is hibernate mapping file?


Hibernate mapping file is used to define the entity bean fields and database table column mappings.
We know that JPA annotations can be used for mapping but sometimes XML mapping file comes
handy when we are using third party classes and we can’t use annotations.

Q) Name some important annotations used for Hibernate mapping?


Hibernate supports JPA annotations and it has some other annotations in org.hibernate.annotations
package. Some of the important JPA and hibernate annotations used are:
javax.persistence.Entity: Used with model classes to specify that they are entity beans.
javax.persistence.Table: Used with entity beans to define the corresponding table name in
database.
javax.persistence.Access: Used to define the access type, either field or property. Default value is
field and if you want hibernate to use getter/setter methods then you need to set it to property.
javax.persistence.Id: Used to define the primary key in the entity bean.
javax.persistence.EmbeddedId: Used to define composite primary key in the entity bean.
javax.persistence.Column: Used to define the column name in database table.
javax.persistence.GeneratedValue: Used to define the strategy to be used for generation of primary
key. Used in conjunction with javax.persistence.GenerationType enum.
javax.persistence.OneToOne: Used to define the one-to-one mapping between two entity beans.
We have other similar annotations as OneToMany, ManyToOne and ManyToMany
org.hibernate.annotations.Cascade: Used to define the cascading between two entity beans, used
with mappings. It works in conjunction with org.hibernate.annotations.CascadeType
javax.persistence.PrimaryKeyJoinColumn: Used to define the property for foreign key. Used with
org.hibernate.annotations.GenericGenerator and org.hibernate.annotations.Parameter
Here are two classes showing usage of these annotations.
package com.journaldev.hibernate.model;

import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;

@Entity
@Table(name = "EMPLOYEE")
@Access(value=AccessType.FIELD)
public class Employee {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "emp_id")
private long id;

@Column(name = "emp_name")
private String name;

@OneToOne(mappedBy = "employee")
@Cascade(value = org.hibernate.annotations.CascadeType.ALL)
private Address address;

//getter setter methods


}
package com.journaldev.hibernate.model;

import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;

@Entity
@Table(name = "ADDRESS")
@Access(value=AccessType.FIELD)
public class Address {

@Id
@Column(name = "emp_id", unique = true, nullable = false)
@GeneratedValue(generator = "gen")
@GenericGenerator(name = "gen", strategy = "foreign", parameters = { @Parameter(name =
"property", value = "employee") })
private long id;
@Column(name = "address_line1")
private String addressLine1;

@OneToOne
@PrimaryKeyJoinColumn
private Employee employee;

//getter setter methods


}

Q) How to configure Hibernate Second Level Cache using EHCache?


EHCache is the best choice for utilizing hibernate second level cache. Following steps are required to
enable EHCache in hibernate application.
Add hibernate-ehcache dependency in your maven project, if it’s not maven then add corresponding
jars.
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>4.3.5.Final</version>
</dependency>
Add below properties in hibernate configuration file.
<property
name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory<
/property>

<!-- For singleton factory -->


<!--<property
name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegio
nFactory</property>
-->

<!-- enable second level cache and query cache -->


<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.use_query_cache">true</property>
<property name="net.sf.ehcache.configurationResourceName">/myehcache.xml</property>
Create EHCache configuration file, a sample file myehcache.xml would look like below.
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
monitoring="autodetect" dynamicConfig="true">

<diskStore path="java.io.tmpdir/ehcache" />

<defaultCache maxEntriesLocalHeap="10000" eternal="false"


timeToIdleSeconds="120" timeToLiveSeconds="120" diskSpoolBufferSizeMB="30"
maxEntriesLocalDisk="10000000" diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU" statistics="true">
<persistence strategy="localTempSwap" />
</defaultCache>

<cache name="employee" maxEntriesLocalHeap="10000" eternal="false"


timeToIdleSeconds="5" timeToLiveSeconds="10">
<persistence strategy="localTempSwap" />
</cache>

<cache name="org.hibernate.cache.internal.StandardQueryCache"
maxEntriesLocalHeap="5" eternal="false" timeToLiveSeconds="120">
<persistence strategy="localTempSwap" />
</cache>

<cache name="org.hibernate.cache.spi.UpdateTimestampsCache"
maxEntriesLocalHeap="5000" eternal="true">
<persistence strategy="localTempSwap" />
</cache>
</ehcache>
Annotate entity beans with @Cache annotation and caching strategy to use. For example,
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

@Entity
@Table(name = "ADDRESS")
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY, region="employee")
public class Address {

}
That’s it, we are done. Hibernate will use the EHCache for second level caching, read Hibernate
EHCache Example for a complete example with explanation.

Q) How to implement Joins in Hibernate?


A) There are various ways to implement joins in hibernate.
 Using associations such as one-to-one, one-to-many etc.
 Using JOIN in the HQL query.
 There is another form “join fetch” to load associated data simultaneously, no lazy loading.
We can fire native SQL query and use join keyword.

Q) What is HQL and what are its benefits?


A) Hibernate Framework comes with a powerful object-oriented query language – Hibernate Query
Language (HQL). It’s very similar to SQL except that we use Objects instead of table names that
makes it more close to object oriented programming. Hibernate query language is case-insensitive
except for java class and variable names. So SeLeCT is the same as sELEct is the same as SELECT, but
com.journaldev.model.Employee is not same as com.journaldev.model.EMPLOYEE. The HQL queries
are cached but we should avoid it as much as possible, otherwise we will have to take care of
associations. However it’s a better choice than native SQL query because of Object-Oriented
approach.

Q) Can we execute native SQL query in hibernate?


A) Hibernate provide option to execute native SQL queries through the use of SQLQuery object.
For normal scenarios, it is however not the recommended approach because we lose benefits
related to hibernate association and hibernate first level caching.

Q) What is the benefit of native SQL query support in hibernate?


A) Native SQL Query comes handy when we want to execute database specific queries that are not
supported by Hibernate API such as query hints or the CONNECT keyword in Oracle Database.

Q) What is Named SQL Query?


A) Hibernate provides Named Query that we can define at a central location and use them
anywhere in the code. We can create named queries for both HQL and Native SQL. Hibernate
Named Queries can be defined in Hibernate mapping files or through the use of JPA annotations
@NamedQuery and @NamedNativeQuery.

Q) What are the benefits of Named SQL Query?


A) Hibernate Named Query helps us in grouping queries at a central location rather than letting
them scattered all over the code. Hibernate Named Query syntax is checked when hibernate session
factory is created, thus making the application fail fast in case of any error in the named queries.
Hibernate Named Query is global, means once defined it can be used throughout the application.
However one of the major disadvantages of Named query is that it’s hard to debug, because we
need to find out the location where it’s defined.

Q) What is the benefit of Hibernate Criteria API?


A) Hibernate provides Criteria API that is more object oriented for querying the database and
getting results. We can’t use Criteria to run update or delete queries or any DDL statements. It’s only
used to fetch the results from the database using more object oriented approach.
Some of the common usages of Criteria API are:
 Criteria API provides Projection that we can use for aggregate functions such as sum(), min(),
max() etc.
 Criteria API can be used with ProjectionList to fetch selected columns only.
 Criteria API can be used for join queries by joining multiple tables, useful methods are
createAlias(), setFetchMode() and setProjection()
 Criteria API can be used for fetching results with conditions, useful methods are add() where we
can add Restrictions.
 Criteria API provides addOrder() method that we can use for ordering the results.
 Learn some quick examples at Hibernate Criteria Example.

Q) How to log hibernate generated SQL queries in log files?


A) We can set below property for hibernate configuration to log SQL queries.
<property name="hibernate.show_sql">true</property>
However we should use it only in Development or Testing environment and turn it off in production
environment.

Q) What is Hibernate Proxy and how it helps in lazy loading?


A) Hibernate uses proxy object to support lazy loading. Basically when you load data from tables,
hibernate doesn’t load all the mapped objects. As soon as you reference a child or lookup object via
getter methods, if the linked entity is not in the session cache, then the proxy code will go to the
database and load the linked object. It uses java assist to effectively and dynamically generate sub-
classed implementations of your entity objects.

Q) How to implement relationships in hibernate?


A) We can easily implement one-to-one, one-to-many and many-to-many relationships in hibernate.
It can be done using JPA annotations as well as XML based configurations.

Q) How transaction management works in Hibernate?


A) Transaction management is very easy in hibernate because most of the operations are not
permitted outside of a transaction. So after getting the session from SessionFactory, we can call
session.beginTransaction() to start the transaction. This method returns the Transaction reference
that we can use later on to either commit or rollback the transaction. Overall hibernate transaction
management is better than JDBC transaction management because we don’t need to rely on
exceptions for rollback. Any exception thrown by session methods automatically rollback the
transaction.

<Q) What is cascading and what are different types of cascading?


When we have relationship between entities, then we need to define how the different operations
will affect the other entity. This is done by cascading and there are different types of it.
Here is a simple example of applying cascading between primary and secondary entities.
import org.hibernate.annotations.Cascade;

@Entity
@Table(name = "EMPLOYEE")
public class Employee {

@OneToOne(mappedBy = "employee")
@Cascade(value = org.hibernate.annotations.CascadeType.ALL)
private Address address;
}

Note that Hibernate CascadeType enum constants are little bit different from JPA
javax.persistence.CascadeType, so we need to use the Hibernate CascadeType and Cascade
annotations for mappings, as shown in above example.
Commonly used cascading types as defined in CascadeType enum are:
None: No Cascading, it’s not a type but when we don’t define any cascading then no operations in
parent affects the child.
ALL: Cascades save, delete, update, evict, lock, replicate, merge, and persist. Basically everything
SAVE_UPDATE: Cascades save and update, available only in hibernate.
DELETE: Corresponds to the Hibernate native DELETE action, only in hibernate.
DETATCH, MERGE, PERSIST, REFRESH and REMOVE – for similar operations
LOCK: Corresponds to the Hibernate native LOCK action.
REPLICATE: Corresponds to the Hibernate native REPLICATE action.

Q) How to integrate log4j logging in hibernate application?


Hibernate 4 uses JBoss logging rather than slf4j used in earlier versions. For log4j configuration, we
need to follow below steps.
1. Add log4j dependencies for maven project, if not maven then add corresponding jar files.
2. Create log4j.xml configuration file or log4j.properties file and keep it in the classpath. You
can keep file name whatever you want because we will load it in next step.
3. For standalone projects, use static block to configure log4j using DOMConfigurator or
PropertyConfigurator. For web applications, you can use ServletContextListener to configure
it.
That’s it, our setup is ready. Create org.apache.log4j.Logger instance in the java classes and start
logging. For complete example code, you should go through Hibernate log4j example and Servlet
log4j example.

Q) How to use application server JNDI DataSource with Hibernate framework?


For web applications, it’s always best to allow servlet container to manage the connection pool.
That’s why we define JNDI resource for DataSource and we can use it in the web application. It’s
very easy to use in Hibernate, all we need is to remove all the database specific properties and use
below property to provide the JNDI DataSource name.
<property name="hibernate.connection.datasource">java:comp/env/jdbc/MyLocalDB</property>
For a complete example, go through Hibernate JNDI DataSource Example.

Q) What are best practices to follow with Hibernate framework?


Some of the best practices to follow in Hibernate are:
 Always check the primary key field access; if it’s generated at the database layer then you should
not have a setter for this.
 By default hibernate set the field values directly, without using setters. So if you want hibernate
to use setters, then make sure proper access is defined as
@Access(value=AccessType.PROPERTY).
 If access type is property, make sure annotations are used with getter methods and not setter
methods. Avoid mixing of using annotations on both filed and getter methods.
 Use native SQL query only when it can’t be done using HQL, such as using database specific
feature.
 If you have to sort the collection, use ordered list rather than sorting it using Collection API.
 Use named queries wisely, keep it at a single place for easy debugging. Use them for commonly
used queries only. For entity specific query, you can keep them in the entity bean itself.
 For web applications, always try to use JNDI DataSource rather than configuring to create
connection in hibernate.
 Avoid Many-to-Many relationships, it can be easily implemented using bidirectional One-to-
Many and Many-to-One relationships.
 For collections, try to use Lists, maps and sets. Avoid array because you don’t get benefit of lazy
loading.
 Do not treat exceptions as recoverable, roll back the Transaction and close the Session. If you do
not do this, Hibernate cannot guarantee that in-memory state accurately represents the
persistent state.
 Prefer DAO pattern for exposing the different methods that can be used with entity bean
 Prefer lazy fetching for associations

Q) What is Hibernate Validator Framework?


Data validation is integral part of any application. You will find data validation at presentation layer
with the use of Javascript, then at the server side code before processing it. Also data validation
occurs before persisting it, to make sure it follows the correct format.
Validation is a cross cutting task, so we should try to keep it apart from our business logic. That’s
why JSR303 and JSR349 provides specification for validating a bean by using annotations. Hibernate
Validator provides the reference implementation of both these bean validation specs. Read more
atHibernate Validation Example.

Q) What is Hibernate Caching?


Caching is a mechanism to enhance the performance of a system. It is a buffer memory that lies
between the application and the database. Cache memory stores recently used data items in order
to reduce the number of database hits as much as possible.
Caching is important to Hibernate as well. It utilizes a multilevel caching scheme as explained below

First-level Cache
The first-level cache is the Session cache and is a mandatory cache through which all requests must
pass. The Session object keeps an object under its own power before committing it to the database.
If you issue multiple updates to an object, Hibernate tries to delay doing the update as long as
possible to reduce the number of update SQL statements issued. If you close the session, all the
objects being cached are lost and either persisted or updated in the database.
Second-level Cache
Second level cache is an optional cache and first-level cache will always be consulted before any
attempt is made to locate an object in the second-level cache. The second level cache can be
configured on a per-class and per-collection basis and mainly responsible for caching objects across
sessions. Any third-party cache can be used with Hibernate. An org.hibernate.cache.CacheProvider
interface is provided, which must be implemented to provide Hibernate with a handle to the cache
implementation.
Query-level Cache
Hibernate also implements a cache for query result sets that integrates closely with the second-
level cache.
This is an optional feature and requires two additional physical cache regions that hold the cached
query results and the timestamps when a table was last updated. This is only useful for queries that
are run frequently with the same parameters.

The Second Level Cache


Hibernate uses first-level cache by default and you have nothing to do to use first-level cache. Let's
go straight to the optional second-level cache. Not all classes benefit from caching, so it's important
to be able to disable the second-level cache. The Hibernate second-level cache is set up in two
steps. First, you have to decide which concurrency strategy to use. After that, you configure cache
expiration and physical cache attributes using the cache provider.
Concurrency Strategies
A concurrency strategy is a mediator, which is responsible for storing items of data in the cache and
retrieving them from the cache. If you are going to enable a second-level cache, you will have to
decide, for each persistent class and collection, which cache concurrency strategy to use.
 Transactional − Use this strategy for read-mostly data where it is critical to prevent stale
data in concurrent transactions, in the rare case of an update.
 Read-write − Again use this strategy for read-mostly data where it is critical to prevent stale
data in concurrent transactions, in the rare case of an update.
 Nonstrict-read-write − This strategy makes no guarantee of consistency between the cache
and the database. Use this strategy if data hardly ever changes and a small likelihood of stale
data is not of critical concern.
 Read-only − A concurrency strategy suitable for data, which never changes. Use it for
reference data only.
If we are going to use second-level caching for our Employee class, let us add the mapping
element required to tell Hibernate to cache Employee instances using read-write strategy.
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name = "Employee" table = "EMPLOYEE">

<meta attribute = "class-description">


This class contains the employee detail.
</meta>

<cache usage = "read-write"/>

<id name = "id" type = "int" column = "id">


<generator class="native"/>
</id>

<property name = "firstName" column = "first_name" type = "string"/>


<property name = "lastName" column = "last_name" type = "string"/>
<property name = "salary" column = "salary" type = "int"/>

</class>
</hibernate-mapping>
The usage="read-write" attribute tells Hibernate to use a read-write concurrency strategy for the
defined cache.
Cache Provider
Your next step after considering the concurrency strategies, you will use your cache candidate
classes to pick a cache provider. Hibernate forces you to choose a single cache provider for the
whole application.
Sr.No. Cache Name & Description

1 EHCache
It can cache in memory or on disk and clustered caching and it supports the
optional Hibernate query result cache.

2 OSCache
Supports caching to memory and disk in a single JVM with a rich set of
expiration policies and query cache support.

3 warmCache
A cluster cache based on JGroups. It uses clustered invalidation, but doesn't
support the Hibernate query cache.

4 JBoss Cache
A fully transactional replicated clustered cache also based on the JGroups
multicast library. It supports replication or invalidation, synchronous or
asynchronous communication, and optimistic and pessimistic locking. The
Hibernate query cache is supported.

Every cache provider is not compatible with every concurrency strategy. The following compatibility
matrix will help you choose an appropriate combination.

Strategy/Provider Read-only Nonstrictread-write Read-write Transactional

EHCache X X X  

OSCache X X X  
SwarmCache X X    

JBoss Cache X     X

You will specify a cache provider in hibernate.cfg.xml configuration file. We choose EHCache as our
second-level cache provider −
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>

<property name = "hibernate.dialect">


org.hibernate.dialect.MySQLDialect
</property>

<property name = "hibernate.connection.driver_class">


com.mysql.jdbc.Driver
</property>

<!-- Assume students is the database name -->

<property name = "hibernate.connection.url">


jdbc:mysql://localhost/test
</property>

<property name = "hibernate.connection.username">


root
</property>

<property name = "hibernate.connection.password">


root123
</property>

<property name = "hibernate.cache.provider_class">


org.hibernate.cache.EhCacheProvider
</property>

<!-- List of XML mapping files -->


<mapping resource = "Employee.hbm.xml"/>

</session-factory>
</hibernate-configuration>

Now, you need to specify the properties of the cache regions. EHCache has its own configuration
file, ehcache.xml, which should be in the CLASSPATH of the application. A cache configuration in
ehcache.xml for the Employee class may look like this −
<diskStore path="java.io.tmpdir"/>

<defaultCache
maxElementsInMemory = "1000"
eternal = "false"
timeToIdleSeconds = "120"
timeToLiveSeconds = "120"
overflowToDisk = "true"
/>

<cache name = "Employee"


maxElementsInMemory = "500"
eternal = "true"
timeToIdleSeconds = "0"
timeToLiveSeconds = "0"
overflowToDisk = "false"
/>
That's it, now we have second-level caching enabled for the Employee class and Hibernate, now hits
the second-level cache whenever you navigate to an Employee or when you load an Employee by
identifier.
You should analyze your all the classes and choose appropriate caching strategy for each of the
classes. Sometime, second-level caching may downgrade the performance of the application. So, it
is recommended to benchmark your application first, without enabling caching and later on enable
your well suited caching and check the performance. If caching is not improving system
performance, then there is no point in enabling any type of caching.

The Query-level Cache


To use the query cache, you must first activate it using the
hibernate.cache.use_query_cache="true" property in the configuration file. By setting this
property to true, you make Hibernate create the necessary caches in memory to hold the query and
identifier sets.
Next, to use the query cache, you use the setCacheable(Boolean) method of the Query class. For
example −
Session session = SessionFactory.openSession();
Query query = session.createQuery("FROM EMPLOYEE");
query.setCacheable(true);
List users = query.list();
SessionFactory.closeSession();
Hibernate also supports very fine-grained cache support through the concept of a cache region. A
cache region is part of the cache that's given a name.
Session session = SessionFactory.openSession();
Query query = session.createQuery("FROM EMPLOYEE");
query.setCacheable(true);
query.setCacheRegion("employee");
List users = query.list();
SessionFactory.closeSession();
This code uses the method to tell Hibernate to store and look for the query in the employee area of
the cache.

You might also like