- get() throws an ObjectNotFoundException if no data is found, while load() returns a proxy object without hitting the database
- When accessing properties of the proxy object returned by load(), it will trigger a SELECT to the database and throw an ObjectNotFoundException if no data exists
- get() immediately hits the database to check for data, while load() defers the database hit until property access if a proxy is returned
- It is generally better to use get() when you expect data to exist, and check for its return value being null, rather than using load()
3. Why we use hibernate?
● Hibernate supports Inheritance, Associations, Collections.
● In hibernate if we save the derived class object, then its base class object will also be stored into the database, it means hibernate
supporting inheritance
● Hibernate supports relationships like One-To-Many,One-To-One, Many-To-Many-to-Many, Many-To-One
● This will also supports collections like List,Set,Map (Only new collections)
● In jdbc all exceptions are checked exceptions, so we must write code in try, catch and throws, but in hibernate we only have Un-checked
exceptions, so no need to write try, catch, or no need to write throws. Actually in hibernate we have the translator which converts checked
to Un-checked ;)
● Hibernate has capability to generate primary keys automatically while we are storing the records into database
● Hibernate has its own query language, i.e hibernate query language which is database independent
● So if we change the database, then also our application will works as HQL is database independent
● HQL contains database independent commands
● While we are inserting any record, if we don’t have any particular table in the database, JDBC will rises an error like “View not exist”, and
throws exception, but in case of hibernate, if it not found any table in the database this will create the table for us ;)
● Hibernate supports caching mechanism by this, the number of round trips between an application and the database will be reduced, by
using this caching technique an application performance will be increased automatically.
● Hibernate supports annotations, apart from XML
● Hibernate provided Dialect classes, so we no need to write sql queries in hibernate, instead we use the methods provided by that API.
● Getting pagination in hibernate is quite simple.
6. Interfaces In Hibernate
● Session Interface : The basic interface for all hibernate applications. The instances are
light weighted and can be created and destroyed without expensive process.
● SessionFactory interface : The delivery of session objects to hibernate applications is
done by this interface. For the whole application, there will be generally one
SessionFactory and can be shared by all the application threads.
● Configuration Interface : Hibernate bootstrap action is configured by this interface. The
location specification is specified by specific mapping documents, is done by the instance
of this interface.
● Transaction Interface : This is an optional interface. This interface is used to abstract
the code from a transaction that is implemented such as a JDBC / JTA transaction.
● Query and Criteria interface : The queries from the user are allowed by this interface
apart from controlling the flow of the query execution.
7. Creating SessionFactory
● Hibernate provides different options to create a SessionFactory instance.
SessionFactory is used for creating multiple lightweight instances of
Session object, which in turn enables database operations. We need not
worry about the performance side of creating/destroying those Hibernate
Session instances because they’re lightweight components.
● On the other side the process of creating instance for Hibernate
SessionFactory is an expensive operation. So we need to exercise
caution while instantiating Hibernate SessionFactory. We can choose to
create the instance through a singleton design pattern.
8. SessionFactory Configurations
● Database connection settings : These attributes comprises the driver class, url of jdbc connection,
username and password for connected schema.
● Hibernate Dialect : As we know, Hibernate is database-agnostic framework, at some point, hibernate
needs to use database specific, extended or native SQL, so hibernate uses dialect configuration to
know which database you’re using so that it can switch to the database specific SQL generator code. If
you’ve omitted this entry, hibernate would provide default one based on the database driver provided.
● Hibernate Session Context : Tracking of session against different contexts can help achieve Create,
Read, Update and Delete operations. Mainly, permitted values are Thread or its corresponding class or
JTA for managed container or its corresponding class. Transaction demarcation concept and all of
these different context are to be discussed later.
12. Hibernate Session
Hibernate SessionFactory is the factory class
through which we get sessions and perform
database operations. Hibernate SessionFactory
provides three methods through which we can
get Session object –
● GetCurrentSession().
● OpenSession().
● openStatelessSession().
13. Hibernate 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 like below.
● <property name="hibernate.current_session_context_class">thread</property>
● If its not configured to thread, then we will get below exception.
Exception in thread "main" org.hibernate.HibernateException: No CurrentSessionContext configured! at
org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1012) at
com.xebia.training.hibernate.orm.criteria.main.HibernateSessionExample.main(HibernateSessionExample.java:16)
●
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. Hibernate Session objects are not thread safe, so we should not use it in multi-threaded
environment. We can use it in single threaded environment because it’s relatively faster than opening a new session.
14. Hibernate openSession()?
● 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. For web
application frameworks, we can choose to open
a new session for each request or for each
session based on the requirement.
●
15. Hibernate 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 like below.
● <property name="hibernate.current_session_context_class">thread</property>
●
Opne Transaction is needed for any operations.
● If its not configured to thread, then we will get below exception.
Exception in thread "main" org.hibernate.HibernateException: No CurrentSessionContext configured!
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1012) at
com.xebia.training.hibernate.orm.criteria.main.HibernateSessionExample.main(HibernateSessionExa
mple.java:16)
●
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. Hibernate Session objects are not thread safe, so we
should not use it in multi-threaded environment. We can use it in single threaded environment because
it’s relatively faster than opening a new session.
16. Hibernate openStatelessSession()?
●
Hibernate SessionFactory openStatelessSession() method returns instance of
StatelessSession. There is another overloaded method where we can pass
java.sql.Connection object to get a stateless session object from hibernate.
●
StatelessSession does not implement first-level cache and it doesn’t interact with any second-
level cache. Since it’s stateless, it doesn’t implement transactional write-behind or automatic
dirty checking or do cascading operations to associated entities.
● Collections are also ignored by a stateless session. Operations performed via a stateless
session bypass Hibernate’s event model and interceptors. It’s more like a normal JDBC
connection and doesn’t provide any benefits that come from using hibernate framework.
●
However, stateless session can be a good fit in certain situations, for example where we are
loading bulk data into database and we don’t want hibernate session to hold huge data in first-
level cache memory.
17. Transaction
A transaction simply represents a unit of work. In such case, if one step fails, the whole transaction fails (which is termed as
atomicity). A transaction can be described by ACID properties (Atomicity, Consistency, Isolation and Durability).
18. Transaction Interface In Hibernate
● In hibernate framework, we have Transaction interface that defines the unit of work. It maintains abstraction
from the transaction implementation (JTA,JDBC).
● AbstractTransactionImpl.java implments TransactionImplemento.java which extends Transaction interface.
– JtaTransaction.java
– JdbcTransaction.java
– CMTTransaction.java
● A transaction is associated with Session and instantiated by calling session.beginTransaction().
● The methods of Transaction interface are as follows:
– void begin() starts a new transaction.
– void commit() ends the unit of work unless we are in FlushMode.NEVER.
– void rollback() forces this transaction to rollback.
– void setTimeout(int seconds) it sets a transaction timeout for any transaction started by a subsequent call to begin on this
instance.
– boolean isAlive() checks if the transaction is still alive.
– void registerSynchronization(Synchronization s) registers a user synchronization callback for this transaction.
– boolean wasCommited() checks if the transaction is commited successfully.
– boolean wasRolledBack() checks if the transaction is rolledback successfully.
19. Hibernate And JPA
● Hibernate with JPA is used for mapping entities or table
together to form a realtionship between those entities.
● We have four type of association we are going to use
and dicuss between entities:
● @OneToOne
● @OneToMany
● @ManyToMany
● @ManyToOne
20. @ManyToOne or @OneToMany
● @ManyToOne annotation defines a single-
valued association to another entity class that
has many-to-one multiplicity. It is not normally
necessary to specify the target entity explicitly
since it can usually be inferred from the type of
the object being referenced.
● @JoinColumn is used to specify a mapped
column for joining an entity association.
21. @OneToOne
● @OneToOne annotation defines a single-
valued association to another entity class that
has one-to-one multiplicity. It is not normally
necessary to specify the target entity explicitly
since it can usually be inferred from the type of
the object being referenced.
● @JoinColumn is used to specify a mapped
column for joining an entity association.
22. @ManyToMany
● @ManyToOne annotation defines a muti-valued
association to another entity class that has
many-to-many multiplicity. It is not normally
necessary to specify the target entity explicitly
since it can usually be inferred from the type of
the object being referenced.
● @JoinTable is used to specify a mapped table
for joining an entity association.
23. Get() and Load() functions?
● Hibernate Session provide different methods to fetch data from database.
Two of them are – get() and load(). There are also a lot of overloaded
methods for these, that we can use in different circumstances.
● At first look both get() and load() seems similar because both of them fetch
the data from database, however there are few differences between them,
let’s look at them with a simple example.
● From the output in the below program it’s clear that get() returns the object
by fetching it from database or from hibernate cache whereas load() just
returns the reference of an object that might not actually exists, it loads the
data from database or cache only when you access other properties of the
object.
24. get() Vs load() Example?
public class HibernateGetVsLoad {
public static void main(String[] args) {
//Prep Work
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
//Get Example
Employee emp = (Employee) session.get(Employee.class, new Long(2));
System.out.println("Employee get called");
System.out.println("Employee ID= "+emp.getId());
System.out.println("Employee Get Details:: "+emp+"n");
//load Example
Employee emp1 = (Employee) session.load(Employee.class, new Long(1));
System.out.println("Employee load called");
System.out.println("Employee ID= "+emp1.getId());
System.out.println("Employee load Details:: "+emp1+"n");
//Close resources
tx.commit();
sessionFactory.close();
}
}
25. Output
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_,
employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as
address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE
employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where
employee0_.emp_id=?
Employee get called
Employee ID= 2
Employee Get Details:: com.xebia.training.hibernate.orm.get_vs_load.model.Employee@2d35da43
Employee load called
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_,
employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as
address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE
employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where
employee0_.emp_id=?
Employee ID= 1
Employee load Details:: com.xebia.training.hibernate.orm.get_vs_load.model.Employee@18f2225f
● From the output it’s clear that get() returns the object by fetching it from database or from hibernate cache
whereas load() just returns the reference of an object that might not actually exists, it loads the data from database
or cache only when you access other properties of the object.
26. NoData found for get() and load()
//Get Example
try{
Employee emp = (Employee) session.get(Employee.class, new Long(200));
System.out.println("Employee get called");
if(emp != null){
System.out.println("Employee GET ID= "+emp.getId());
System.out.println("Employee Get Details:: "+emp+"n");
}
}catch(Exception e){
e.printStackTrace();
}
//load Example
try{
Employee emp1 = (Employee) session.load(Employee.class, new Long(100));
System.out.println("Employee load called");
System.out.println("Employee LOAD ID= "+emp1.getId());
System.out.println("Employee load Details:: "+emp1+"n");
}catch(Exception e){
e.printStackTrace();
}
27. Output
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary
as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as
city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on
employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
Employee get called
Employee load called
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary
as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as
city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on
employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
org.hibernate.ObjectNotFoundException: No row with the given identifier exists:
[com.xebia.training.hibernate.orm.get_vs_load.model.Employee#100]
at org.hibernate.internal.SessionFactoryImpl$1$1.handleEntityNotFound(SessionFactoryImpl.java:253)
at org.hibernate.proxy.AbstractLazyInitializer.checkTargetState(AbstractLazyInitializer.java:262)
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:176)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:286)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
at com.xebia.training.hibernate.orm.get_vs_load.model.Employee_$$_jvst515_1.getId(Employee_$$_jvst515_1.java)
at
com.xebia.training.hibernate.orm.get_vs_load.main.GetVsLoadNoDataInDBExample.main(GetVsLoadNoDataInDBExample.java:3
5)
28. Overloaded methods
Let’s look at some of the overloaded methods too. Above get() and load()
methods could have been written as below too.
● Employee emp = (Employee)
session.get("com.journaldev.hibernate.model.Employee", new Long(2));
● Employee emp1 = (Employee)
session.load("com.journaldev.hibernate.model.Employee", new Long(1));
● Employee emp2 = new Employee();
session.load(emp1, new Long(1));
There are other methods with LockOptions argument but I haven’t used them.
Notice that we need to pass full class name as argument.
29. Differences between get() vs load()
● 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.
● Since load() throws exception when data is not
found, we should use it only when we know data
exists.
● We should use get() when we want to make sure
data exists in the database.
31. SQL/HQL Queries
● 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.
32. Clauses in HQL
● From Clause: It’s same as select clause in SQL, from Employee is same as select
* from Employee. We can also create alias such as from Employee emp or from
Employee as emp.
● Join Clause: HQL supports inner join, left outer join, right outer join and full join. For
example, select e.name, a.city from Employee e INNER JOIN e.address a. In this
query, Employee class should have a variable named address. We will look into it
in the example code.
● Aggregate Functions: HQL supports commonly used aggregate functions such as
count(*), count(distinct x), min(), max(), avg() and sum().
●
Expressions: HQL supports arithmetic expressions (+, -, *, /), binary comparison
operators (=, >=, <=, <>, !=, like), logical operations (and, or, not) etc.
● HQL also supports ordre by and group by clauses.
● HQL also supports sub-queries just like SQL queries.
● HQL supports DDL, DML and executing store procedures too.
38. Concurrency Strategy
● 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
41. Configuration Parameter
● hibernate.cache.region.factory_class is used to define the Factory class for Second
level caching, I am using org.hibernate.cache.ehcache.EhCacheRegionFactory for this.
If you want the factory class to be singleton, you should use
org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory class.
If you are using Hibernate 3, corresponding classes will be
net.sf.ehcache.hibernate.EhCacheRegionFactory and
net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory.
● hibernate.cache.use_second_level_cache is used to enable the second level cache.
● hibernate.cache.use_query_cache is used to enable the query cache, without it HQL
queries results will not be cached.
● net.sf.ehcache.configurationResourceName is used to define the EHCache
configuration file location, it’s an optional parameter and if it’s not present EHCache will try
to locate ehcache.xml file in the application classpath.
43. Criteria API
● Most of the times, we prefer HQL for querying the database
and getting the results. HQL is not preferred way for updating
or deleting values because then we need to take care of any
associations between tables.
● 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.
44. Common usage of Criteria API
● 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.