Hibernate
Hibernate
Hibernate
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.
Hibernate
1
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, its 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 its required.
7.
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.
Hibernate removes a lot of boiler-plate code that comes with JDBC API, the code looks more
cleaner and readable.
2.
Hibernate supports inheritance, associations and collections. These features are not present
with JDBC API.
3.
Hibernate implicitly provides transaction management, in fact most of the queries cant 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.
4.
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 its redundant in every JDBC call and used for
Hibernate
2
Hibernate Query Language (HQL) is more object oriented and close to java programming
language. For JDBC, we need to write native sql queries.
6.
Hibernate supports caching that is better for performance, JDBC queries are not cached
hence performance is low.
7.
Hibernate provide option through which we can create database tables too, for JDBC tables
must exist in the database.
8.
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.
9.
SessionFactory (org.hibernate.SessionFactory): SessionFactory is an immutable threadsafe 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.
2.
Hibernate
3
3.
javax.persistence.Entity: Used with model classes to specify that they are entity beans.
2.
javax.persistence.Table: Used with entity beans to define the corresponding table name in
database.
3.
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.
4.
Hibernate
4
5.
6.
7.
8.
9.
10.
notations.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;
Hibernate
5
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;
Hibernate
6
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 {
Hibernate
7
@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;
SessionFactory also provide methods to get the Class metadata and Statistics instance to
get the stats of query executions, second level cache details etc.
10.
Internal state of SessionFactory is immutable, so its thread safe. Multiple threads can
access it simultaneously to get Session instances.
12.
Hibernate Session object is not thread safe, every thread should get its own session
instance and close it after its work is finished.
13.
What is difference between openSession and
getCurrentSession?
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 dont 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
9
14.
What is difference between Hibernate Session get() and
load() method?
Hibernate session comes with different methods to load data from database. get and load
are most used methods, at first look they seems similar but there are some differences
between them.
1.
get() loads the data as soon as its called whereas load() returns a proxy object and loads
data only when its actually required, so load() is better because it support lazy loading.
2.
Since load() throws exception when data is not found, we should use it only when we know
data exists.
3.
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.
15.
What is hibernate caching? Explain Hibernate first level
cache?
As the name suggests, hibernate caches query data to make our application faster.
Hibernate Cache can be very useful in gaining fast application performance if used correctly.
The idea behind cache is to reduce the number of database queries, hence reducing the
throughput time of the application.
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.
Hibernate
10
16.
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.
1.
Add hibernate-ehcache dependency in your maven project, if its not maven then add
corresponding jars.
<dependency>
2.
3.
<groupId>org.hibernate</groupId>
4.
<artifactId>hibernate-ehcache</artifactId>
5.
<version>4.3.5.Final</version>
</dependency>
6.
<property
7.
name="hibernate.cache.region.factory_class">org.hibernate.cache.e
hcache.EhCacheRegionFactory</property>
8.
9.
10.
<!-- <property
name="hibernate.cache.region.factory_class">org.hibernate.cach
e.ehcache.SingletonEhCacheRegionFactory</property>
11.
Hibernate
11
-->
12.
13.
14.
<property
name="hibernate.cache.use_second_level_cache">true</property>
<property
15.
name="hibernate.cache.use_query_cache">true</property>
<property
name="net.sf.ehcache.configurationResourceName">/myehcache.xml</p
roperty>
16.
Create EHCache configuration file, a sample file myehcache.xml would look like below.
17.
18.
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xsi:noNamespaceSchemaLocation="ehcache.xsd"
19.
updateCheck="true"
monitoring="autodetect" dynamicConfig="true">
20.
21.
22.
23.
<defaultCache maxEntriesLocalHeap="10000"
24.
eternal="false"
timeToIdleSeconds="120" timeToLiveSeconds="120"
25.
diskSpoolBufferSizeMB="30"
Hibernate
12
maxEntriesLocalDisk="10000000"
26.
diskExpiryThreadIntervalSeconds="120"
27.
memoryStoreEvictionPolicy="LRU" statistics="true">
28.
29.
30.
31.
eternal="false"
32.
timeToIdleSeconds="5" timeToLiveSeconds="10">
33.
34.
35.
<cache
36.
name="org.hibernate.cache.internal.StandardQueryCache"
maxEntriesLocalHeap="5" eternal="false"
37.
timeToLiveSeconds="120">
<persistence strategy="localTempSwap" />
38.
</cache>
39.
40.
<cache
41.
name="org.hibernate.cache.spi.UpdateTimestampsCache"
42.
maxEntriesLocalHeap="5000" eternal="true">
43.
Hibernate
13
</cache>
44.
</ehcache>
45.
Annotate entity beans with @Cache annotation and caching strategy to use. For example,
46.
import org.hibernate.annotations.Cache;
47.
import org.hibernate.annotations.CacheConcurrencyStrategy;
48.
49.
@Entity
50.
@Table(name = "ADDRESS")
51.
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY,
region="employee")
52.
53.
}
Thats it, we are done. Hibernate will use the EHCache for second level caching,
read Hibernate EHCache Example for a complete example with explanation.
Transient: When an object is never persisted or associated with any session, its in transient
state. Transient instances may be made persistent by calling save(), persist() or
saveOrUpdate(). Persistent instances may be made transient by calling delete().
Hibernate
14
2.
Persistent: When an object is associated with a unique session, its 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, its
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().
2.
3.
4.
Hibernate
15
Hibernate uses Reflection API to create instance of Entity beans, usually when you call get()
or load() methods. The method Class.newInstance() is used for this and it requires no-args
constructor. So if you wont have no-args constructor in entity beans, hibernate will fail to
instantiate it and you will getHibernateException.
5.
6.
Bag
2.
Set
3.
List
4.
Array
Hibernate
16
5.
7.
Map
2.
Using JOIN in the HQL query. There is another form join fetch to load associated data
simultaneously, no lazy loading.
3.
Hibernate
17
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");
Hibernate
18
Hibernate Named Queries can be defined in Hibernate mapping files or through the use of
JPA annotations @NamedQuery and @NamedNativeQuery.
Criteria API provides Projection that we can use for aggregate functions such as sum(),
min(), max() etc.
2.
Criteria API can be used with ProjectionList to fetch selected columns only.
3.
Criteria API can be used for join queries by joining multiple tables, useful methods are
createAlias(), setFetchMode() and setProjection()
4.
Criteria API can be used for fetching results with conditions, useful methods are add() where
we can add Restrictions.
5.
Criteria API provides addOrder() method that we can use for ordering the results.
2.
3.
2.
Hibernate
20
3.
@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
JPAjavax.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:
Hibernate
21
1.
None: No Cascading, its not a type but when we dont define any cascading then no
operations in parent affects the child.
2.
ALL: Cascades save, delete, update, evict, lock, replicate, merge, persist. Basically
everything
3.
4.
5.
6.
7.
4.
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.
Thats 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.
Hibernate
22
For web applications, its always best to allow servlet container to manage the connection
pool. Thats why we define JNDI resource for DataSource and we can use it in the web
application. Its 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</pr
operty>
For a complete example, go through Hibernate JNDI DataSource Example.
2.
Create Model classes and corresponding DAO implementations for database operations.
Note that DAO classes will use SessionFactory that will be injected by Spring Bean
configuration.
3.
n ororg.springframework.orm.hibernate3.annotation.AnnotationSessi
onFactoryBean in Spring Bean configuration file. For Hibernate 4, there is single
classorg.springframework.orm.hibernate4.LocalSessionFactoryBean tha
t should be configured.
4.
Note that we dont need to use Hibernate Transaction Management, we can leave it to
Spring declarative transaction management using @Transactional annotation.
Hibernate
23
For complete example go through Spring Hibernate Integration and Spring MVC Hibernate
Integration.
2.
Session from Hibernate and get the benefit of Spring transaction management. However
from Hibernate 3.0.1, we can use SessionFactory getCurrentSession() method to get the
current session and use it to get the spring transaction management benefits. If you go
through above examples, you will see how easy it is and thats why we should not use these
classes anymore.
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.
3.
4.
Domain Model Pattern An object model of the domain that incorporates both behavior and
data.
2.
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.
3.
Hibernate
24
4.
Always check the primary key field access, if its generated at the database layer then you
should not have a setter for this.
2.
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).
3.
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.
4.
Use native sql query only when it cant be done using HQL, such as using database specific
feature.
5.
If you have to sort the collection, use ordered list rather than sorting it using Collection API.
6.
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.
7.
For web applications, always try to use JNDI DataSource rather than configuring to create
connection in hibernate.
8.
Avoid Many-to-Many relationships, it can be easily implemented using bidirectional One-toMany and Many-to-One relationships.
9.
For collections, try to use Lists, maps and sets. Avoid array because you dont get benefit of
lazy loading.
10.
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.
Hibernate
25
11.
Prefer DAO pattern for exposing the different methods that can be used with entity bean
12.
Hibernate
26