Devjournals - Hibernate
Devjournals - Hibernate
Hibernate is one of the most widely used ORM tool for Java applications. It’s used a lot in enterprise
applications for database operations. So I decided to write a post about hibernate interview questions to
brush up your knowledge before the interview.
Whether you are fresher or experienced, having good knowledge or Hibernate ORM tool helps in cracking
interview. Here I am providing important hibernate interview questions with answers to help you brush up
your knowledge and impress your interviewer. Just like other interview questions posts, chances are that I
will be adding more questions to this list in future, so you might want to bookmark it for future reference.
Recently I have written a lot of posts on hibernate, most of them contains complete downloadable projects.
I will provide reference to them as and when needed and you can go through them to refresh your
knowledge.
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. For a quick overview of hibernate framework usage, you can go through Hibernate
Beginners Tutorial.
JPA specifications is defined with annotations in javax.persistence package. Using JPA annotation helps us
in writing implementation independent code.
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.
Overall hibernate is the best choice in current market for ORM tool, it contains all the features that you will
ever need in an ORM tool.
9. Hibernate removes a lot of boiler-plate code that comes with JDBC API, the code looks more
cleaner and readable.
10. Hibernate supports inheritance, associations and collections. These features are not present
with JDBC API.
11. 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. Read more at JDBC Transaction Management.
12. 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.
13. Hibernate Query Language (HQL) is more object oriented and close to java programming
language. For JDBC, we need to write native sql queries.
14. Hibernate supports caching that is better for performance, JDBC queries are not cached hence
performance is low.
15. Hibernate provide option through which we can create database tables too, for JDBC tables
must exist in the database.
16. Hibernate configuration helps us in using JDBC like connection as well as JNDI DataSource for
connection pool. This is very important feature in enterprise application and completely missing
in JDBC API.
17. Hibernate supports JPA annotations, so code is independent of implementation and easily
replaceable with other ORM tools. JDBC code is very tightly coupled with the application.
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)
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "emp_id")
private long id;
@Column(name = "emp_name")
@OneToOne(mappedBy = "employee")
@Cascade(value = org.hibernate.annotations.CascadeType.ALL)
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)
@Id
@GeneratedValue(generator = "gen")
@GenericGenerator(name = "gen", strategy = "foreign", parameters = {
@Parameter(name = "property", value = "employee") })
@Column(name = "address_line1")
@OneToOne
@PrimaryKeyJoinColumn
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.
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.
<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.
31. get() loads the data as soon as it’s called whereas load() returns a proxy object and loads data
only when it’s actually required, so load() is better because it support lazy loading.
32. Since load() throws exception when data is not found, we should use it only when we know data
exists.
33. We should use get() when we want to make sure data exists in the database.
For clarification regarding the differences, please read Hibernate get vs load.
Hibernate first level cache is associated with the Session object. Hibernate first level cache is enabled by
default and there is no way to disable it. However hibernate provides methods through which we can delete
selected objects from the cache or clear the cache completely.
Any object cached in a session will not be visible to other sessions and when the session is closed, all the
cached objects will also be lost.
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>
<property
name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcac
he.EhCacheRegionFactory</property>
<!-- <property
name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcac
he.SingletonEhCacheRegionFactory</property>
-->
<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</prope
rty>
Create EHCache configuration file, a sample file myehcache.xml would look like below.
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
monitoring="autodetect" dynamicConfig="true">
timeToIdleSeconds="120" timeToLiveSeconds="120"
diskSpoolBufferSizeMB="30"
maxEntriesLocalDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU" statistics="true">
</defaultCache>
timeToIdleSeconds="5" timeToLiveSeconds="10">
</cache>
<cache name="org.hibernate.cache.internal.StandardQueryCache"
maxEntriesLocalHeap="5" eternal="false"
timeToLiveSeconds="120">
</cache>
<cache name="org.hibernate.cache.spi.UpdateTimestampsCache"
maxEntriesLocalHeap="5000" eternal="true">
</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")
}
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.
1. 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().
2. 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.
3. 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().
Hibernate persist is similar to save with transaction. I feel it’s better than save because we can’t use it
outside the boundary of transaction, so all the object mappings are preserved. Also persist doesn’t return
the generated id immediately, so data persistence happens when needed.
Hibernate saveOrUpdate results into insert or update queries based on the provided data. If the data is
present in the database, update query is executed. We can use saveOrUpdate() without transaction also,
but again you will face the issues with mapped objects not getting saved if session is not flushed. For
example usage of these methods, read Hibernate save vs persist.
.addOrder(Order.desc("id")).li
st();
Ordered list is better than sorted list because the actual sorting is done at database level, that is fast and
doesn’t cause memory issues.
4. Bag
5. Set
6. List
7. Array
8. Map
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. Read more at HQL Example.
<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.setCacheable(true);
query.setCacheRegion("ALL_EMP");
For normal scenarios, it is however not the recommended approach because we loose benefits related to
hibernate association and hibernate first level caching. Read more at Hibernate Native SQL Query
Example.
Hibernate Named Queries can be defined in Hibernate mapping files or through the use of JPA annotations
@NamedQuery and @NamedNativeQuery.
However one of the major disadvantage of Named query is that it’s hard to debug, because we need to find
out the location where it’s defined.
<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.
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.
Here is a simple example of applying cascading between primary and secondary entities.
import org.hibernate.annotations.Cascade;
@Entity
@Table(name = "EMPLOYEE")
@OneToOne(mappedBy = "employee")
@Cascade(value = org.hibernate.annotations.CascadeType.ALL)
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:
20. None: No Cascading, it’s not a type but when we don’t define any cascading then no operations
in parent affects the child.
21. ALL: Cascades save, delete, update, evict, lock, replicate, merge, persist. Basically everything
22. SAVE_UPDATE: Cascades save and update, available only in hibernate.
23. DELETE: Corresponds to the Hibernate native DELETE action, only in hibernate.
24. DETATCH, MERGE, PERSIST, REFRESH and REMOVE – for similar operations
25. LOCK: Corresponds to the Hibernate native LOCK action.
26. REPLICATE: Corresponds to the Hibernate native REPLICATE action.
Add log4j dependencies for maven project, if not maven then add corresponding jar files.
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.
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.
For complete example go through Spring Hibernate Integration and Spring MVC Hibernate Integration.
One other benefit of HibernateTemplate was exception translation but that can be achieved easily by
using @Repository annotation with service classes, shown in above spring mvc example. This is a trick
question to judge your knowledge and whether you are aware of recent developments or not.
Domain Model Pattern – An object model of the domain that incorporates both behavior and
data.
Data Mapper – A layer of Mappers that moves data between objects and a database while
keeping them independent of each other and the mapper itself.
Proxy Pattern for lazy loading
Factory pattern in SessionFactory
43.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
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 at Hibernate
Validation Example.
That’s all for Hibernate Interview Questions and Answers, I hope it will help you for interview as a
fresher or experienced person. Please let me know if I have missed any important question here, I will add
that to the list.