Hibernate notes
Hibernate notes
1.What is ORM ?
ORM stands for object/relational mapping. ORM is the automated persistence of objects in a Java
application to the tables in a relational database.
load() get()
Only use the load() method if you are sure that the If you are not sure that the object exists,
object exists. then use one of the get() methods.
load() method will throw an exception if the get() method will return null if the
unique id is not found in the database. unique id is not found in the database.
load() just returns a proxy by default and database get() will hit the database immediately.
won’t be hit until the proxy is first invoked.
23.Define HibernateTemplate?
org.springframework.orm.hibernate.HibernateTemplate is a helper class which provides
different methods for querying/retrieving data from the database. It also converts checked
HibernateExceptions into unchecked DataAccessExceptions.
26.If you want to see the Hibernate generated SQL statements on console, what should we do?
In Hibernate configuration file set as follows:
<property name="show_sql">true</property>
If your collection is not large, it will be more If your collection is very large, it will be more
efficient way to sort it. efficient way to sort it .
JDBC Hibernate
Inner Join
1.
List<Object[]> africanContinents = session.createQuery(
"from Continent cont join cont.countries ctry " +
"where cont.name = 'Africa'")
.list();
Query
select
COUNTRY.CTRY_ID,
COUNTRY.AREA,
CONTINENT.CONT_ID,
CONTINENT.CONT_NAME,
COUNTRY.CURRENCY,
COUNTRY.CTRY_NAME,
COUNTRY.POP,
COUNTRY.POP_UPD_ON
from
CONTINENT
inner join
COUNTRY
on CONTINENT.CONT_ID=COUNTRY.CONT_ID
where
CONT_NAME='Africa'
2.
List<String> continentsWithBigCountries = session.createQuery(
"select distinct cont.name " +
"from Continent cont join cont.countries ctry " +
"where ctry.area > 100000")
.list();
Query
select
distinct CONT_NAME
from
CONTINENT
inner join
COUNTRY
on CONTINENT.CONT_ID=COUNTRY.CONT_ID
where
AREA>100000
Outer Join
1.
List<Object[]> allContinentsAndCountries = session.createQuery(
"select cont.name, nvl(ctry.name, '[none]') " +
"from Continent cont left join cont.countries ctry " +
"with ctry.area > 100000 " +
"order by cont.name")
.list();
select
CONT_NAME,
nvl(CTRY_NAME, '[none]')
from
CONTINENT
left outer join
COUNTRY
on CONTINENT.CONT_ID=COUNTRY.CONT_ID
and (
AREA>100000
)
order by
CONT_NAME
3.Theta-Style Joins
Theta-style joins use a more traditional join syntax by specifying a comma separated list of
classes in the from clause and the join condition in thewhere clause.
This query returns any continents that share a name with a country:
List<Continent> sameNames = session.createQuery(
"select cont " +
"from Continent cont, Country ctry " +
"where cont.name = ctry.name")
.list();
The from and where clauses are almost identical in the generated SQL.
select
CONTINENT.CONT_ID,
CONTINENT.CONT_NAME
from
CONTINENT,
COUNTRY
where
CONTINENT.CONT_NAME=COUNTRY.CTRY_NAME
The main reason to use theta-style syntax is to specify a join that is not mapped with an
association.
4.Fetch
Fetch
Suppose we retrieve a Continent object using HQL knowing that we will be accessing the
Country objects that belong to that Continent. We join to the Country class to retrieve the
data in one SQL statement.
Continent europe = (Continent) session.createQuery(
"select cont " +
"from Continent cont join cont.countries " +
"where cont.name = 'Europe'")
.uniqueResult();
The uniqueResult() method generates SQL which includes a join to the COUNTRY table.
select
CONTINENT.CONT_ID,
CONTINENT.CONT_NAME
from
CONTINENT
inner join
COUNTRY
on CONTINENT.CONT_ID=COUNTRY.CONT_ID
where
CONT_NAME='Europe'
However, if we take a look at the select clause, we can see that no Country data has been
returned.
Now suppose we wish to see the number of countries in Europe.
europe.getCountries().size()
To eagerly fetch the Country objects using a single SQL statement, add the fetch keyword to
the HQL query.
Continent europe = (Continent) session.createQuery(
"select cont " +
"from Continent cont join fetch cont.countries " +
"where cont.name = 'Europe'")
.uniqueResult();
This time, the following SQL is generated by uniqueResult() and all the objects are
populated in the countries collection, immediately:
select
CONTINENT.CONT_ID,
COUNTRY.CTRY_ID ,
CONTINENT.CONT_NAME,
COUNTRY.AREA,
COUNTRY.CURRENCY,
COUNTRY.CTRY_NAME,
COUNTRY.POP,
COUNTRY.POP_UPD_ON
from
CONTINENT
inner join
COUNTRY
on CONTINENT.CONT_ID=COUNTRY.CONT_ID
where
CONT_NAME='Europe'
The getCountries().size() method now accesses the in memory list without executing any
further SQL.
My Analysis On HQL
HQL
select con , adr from com.ebix.sosync.domain.Contact as con
join con.addresses adr
where con.contactId < 1000
select
<<contact all fields , address all fields>>
from
Contact contact0_
inner join
Address addresses1_
on contact0_.contactId=addresses1_.CONTACTID
where
contact0_.contactId<1000
2.
select con , adr from com.ebix.sosync.domain.Contact as con
left join con.addresses adr
where con.contactId < 1000
Query
select
<<All contact and Address fileds>>
Contact contact0_
left outer join
Address addresses1_
on contact0_.contactId=addresses1_.CONTACTID
where
contact0_.contactId<1000
So when we use Left Join internally Hibernate converts it into left outer
join
When we use fetch the Hibernate will internally Fetch All the records from
the join table
Difference between get and load method in Hibernate is a one of the most popular question asked in
Hibernate and spring interviews. Hibernate Session class provides two method to access object e.g.
session.get() and session.load() both looked quite similar to each other but there are subtle difference
between load and get method which can affect performance of application. Main difference between get() vs
load method is that get() involves database hit if object doesn't exists in Session Cache and returns a fully
initialized object which may involve several database call while load method can return proxy in place and
only initialize the object or hit the database if any method other than getId() is called on persistent or entity
object. This lazy initialization can save couple of database round-trip which result in better performance.
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
By far most important difference between get and load in my opinion. 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.
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. As stated in difference number 2 between get and load in Hibernate. 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 there
behavior which makes them different.
That’s all on difference between get and load in Hibernate. No doubt Hibernate is a great tool for Object relational
mapping but knowing this subtle differences can greatly help to improver performance of your J2EE application, apart
from practical reason get vs load method is also frequently asked questions in Hibernate interview, so familiarity with
differences between load and get certainly helps.
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) One more thing which differentiate persist and save method in Hibernate is that is there behavior on outside of
transaction boundaries. 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.
This Hibernate Interview question is related to query functionality provided by 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.
This Hibernate Interview question is related to query functionality provided by 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.
What is SessionFactory in Hibernate? is SessionFactory thread-safe?
Another common Interview questions related to Hibernate framework. 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. It acts as single data store and its also thread-safe so that multiple thread
can use same SessionFactory. 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. Also internal state ofSessionFactory,
which contains all meta data about Object/Relational mapping is Immutable and can not be changed once created.
What is Session in Hibernate? Can we share single Session among multiple threads in Hibernate?
This is usually asked as follow-up question of previous Hibernate Interview question. After SessionFactory its
time for Session. Session represent a small unit of work in Hibernate, they maintain connection with database
and they are not thread-safe, it means you can not share Hibernate Session between multiple threads. Though
Session obtains database connection lazily it's good to close session as soon as you are done with it.
This is one of the easy Hibernate interview question you ever face. A sorted collection is sorted in memory by
using Java Comparator, while a 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.
In Hibernate, Object can remain in three state transient, persistent or detached. An object which is
associated with Hibernate session is called persistent object. 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. On the other hand if an object which is earlier associated with Session,
but currently not associated with it are called detached object. You can reattach detached object to any other
session by calling either update() or saveOrUpdate() method on that session. Transient objects are newly
created instance of persistence class, which is never associated with any Hibernate Session. Similarly you can
call persist() or save() methods to make transient object persistent. Just remember, here transient doesn’t
represent transient keyword in Java, which is altogether different thing.
This one is one of the tricky Hibernate Interview question, because Session's lock() method reattach object
without synchronizing or updating with database. So you need to be very careful while using lock() method. By
the way you can always use Session's update() method to sync with database during reattachment. Some time
this Hibernate question is also asked as what is difference between Session's lock() and update() method. You can
use this key point to answer that question as well.
This is one of the first interview question related to caching in Hibernate, you can expect few more. Second level
Cache is maintained at SessionFactory level and can improve performance by saving few database round trip.
Another worth noting point is that second level cache is available to whole application rather than any particular
session.
Yes, you can make an 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.