Category Archives: Hibernate

Some Useful Hibernate Interview questions with answers

Q1. How will you configure Hibernate?

Answer:

The configuration files hibernate.cfg.xml (or hibernate.properties) and mapping files *.hbm.xml are used by the Configuration class to create (i.e. configure and bootstrap hibernate) the SessionFactory, which in turn creates the Session instances. Session instances are the primary interface for the persistence service.

hibernate.cfg.xml (alternatively can use hibernate.properties): These two files are used to configure the hibernate sevice (connection driver class, connection URL, connection username, connection password, dialect etc). If both files are present in the classpath then hibernate.cfg.xml file overrides the settings found in the hibernate.properties file.

Mapping files (*.hbm.xml): These files are used to map persistent objects to a relational database. It is the best practice to store each object in an individual mapping file (i.e mapping file per class) because storing large number of persistent classes into one mapping file can be difficult to manage and maintain. The naming convention is to use the same name as the persistent (POJO) class name. For example Account.class will have a mapping file named Account.hbm.xml. Alternatively hibernate annotations can be used as part of your persistent class code instead of the *.hbm.xml files.

Q2. What is a SessionFactory? Is it a thread-safe object?

Answer:

SessionFactory is Hibernate’s concept of a single datastore and is threadsafe so that many threads can access it concurrently and request for sessions and immutable cache of compiled mappings for a single database. A SessionFactory is usually only built once at startup. SessionFactory should be wrapped in some kind of singleton so that it can be easily accessed in an application code.

SessionFactory sessionFactory = new Configuration().configure().buildSessionfactory();

Q3. What is a Session? Can you share a session object between different theads?

Answer:

Session is a light weight and a non-threadsafe object (No, you cannot share it between threads) that represents a single unit-of-work with the database. Sessions are opened by a SessionFactory and then are closed when all work is complete. Session is the primary interface for the persistence service. A session obtains a database connection lazily (i.e. only when required). To avoid creating too many sessions ThreadLocal class can be used as shown below to get the current session no matter how many times you make call to the currentSession() method.

public class HibernateUtil {

public static final ThreadLocal local = new ThreadLocal();

public static Session currentSession() throws HibernateException {
Session session = (Session) local.get();
//open a new session if this thread has no session
if (session == null) {
    session = sessionFactory.openSession();
    local.set(session);
   }
   return session;
  }
}

It is also vital that you close your session after your unit of work completes. Note: Keep your Hibernate Session API handy.

Q4. What are the benefits of detached objects?

Answer:

Detached objects can be passed across layers all the way up to the presentation layer without having to use any DTOs (Data Transfer Objects). You can later on re-attach the detached objects to another session.

Q5. What are the pros and cons of detached objects?

Answer:

pros:

When long transactions are required due to user think-time, it is the best practice to break the long transaction up into two or more transactions. You can use detached objects from the first transaction to carry data all the way up to the presentation layer. These detached objects get modified outside a transaction and later on re-attached to a new transaction via another session.

Cons

In general, working with detached objects is quite cumbersome, and better to not clutter up the session with them if possible. It is better to discard them and re-fetch them on subsequent requests. This approach is not only more portable but also more efficient because – the objects hang around in Hibernate’s cache anyway.

Also from pure rich domain driven design perspective it is recommended to use DTOs (DataTransferObjects) and DOs (DomainObjects) to maintain the separation between Service and UI tiers.

Q6. How does Hibernate distinguish between transient (i.e. newly instantiated) and detached objects?

Answer

” Hibernate uses the version property, if there is one.
” If not uses the identifier value. No identifier value means a new object. This does work only for Hibernate managed surrogate keys. Does not work for natural keys and assigned (i.e. not managed by Hibernate) surrogate keys.
” Write your own strategy with Interceptor.isUnsaved().

Q7. What is the difference between the session.get() method and the session.load() method?

Answer:

Both the session.get(..) and session.load() methods create a persistent object by loading the required object from the database. But if there was not such object in the database then the method session.load(..) throws an exception whereas session.get(&) returns null.

Q8. What is the difference between the session.update() method and the session.lock() method?

Answer:

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 detached object or if it does not matter because you will be overwriting all the columns that would have changed later on within the same transaction.

Note: When you reattach detached objects you need to make sure that the dependent objects are reatched as well.

Q9. How would you reatach detached objects to a session when the same object has already been loaded into the session?

Answer:

You can use the session.merge() method call.

Q10. What are the general considerations or best practices for defining your Hibernate persistent classes?

Answer:


1.You must have a default no-argument constructor for your persistent classes and there should be getXXX() (i.e accessor/getter) and setXXX( i.e. mutator/setter) methods for all your persistable instance variables.

2.You should implement the equals() and hashCode() methods based on your business key and it is important not to use the id field in your equals() and hashCode() definition if the id field is a surrogate key (i.e. Hibernate managed identifier). This is because the Hibernate only generates and sets the field when saving the object.

3. It is recommended to implement the Serializable interface. This is potentially useful if you want to migrate around a multi-processor cluster.

4.The persistent class should not be final because if it is final then lazy loading cannot be used by creating proxy objects.

5.Use XDoclet tags for generating your *.hbm.xml files or Annotations (JDK 1.5 onwards), which are less verbose than *.hbm.xml files.

Hibernate Caching Tutorial

(1) Why Need ?

While working with Hibernate web applications we will face so many problems in its performance due to database traffic. That to when the database traffic is very heavy . Actually hibernate is well used just because of its high performance only. So some techniques are necessary to maintain its performance. Caching is the best technique to solve this problem. In this article we will discuss about, how we can improve the performance of Hibernate web applications using caching.

The performance of Hibernate web applications is improved using caching by optimizing the database applications. The cache actually stores the data already loaded from the database, so that the traffic between our application and the database will be reduced when the application want to access that data again. Maximum the application will works with the data in the cache only. Whenever some another data is needed, the database will be accessed. Because the time needed to access the database is more when compared with the time needed to access the cache. So obviously the access time and traffic will be reduced between the application and the database. Here the cache stores only the data related to current running application. In order to do that, the cache must be cleared time to time whenever the applications are changing.

Hibernate uses two different caches for objects: first-level cache and second-level cache..

1.1) First-level cache

First-level cache always Associates with the Session object. Hibernate uses this cache by default. Here, it processes one transaction after another one, means wont process one transaction many times. Mainly it reduces the number of SQL queries it needs to generate within a given transaction. That is instead of updating after every modification done in the transaction, it updates the transaction only at the end of the transaction.

1.2) Second-level cache

Second-level cache always associates with the Session Factory object. While running the transactions, in between it loads the objects at the Session Factory level, so that those objects will available to the entire application, don’t bounds to single user. Since the objects are already loaded in the cache, whenever an object is returned by the query, at that time no need to go for a database transaction. In this way the second level cache works. Here we can use query level cache also. Later we will discuss about it.

(2) Way to Implement It

Hibernate supports four open-source cache implementations named EHCache (Easy Hibernate Cache), OSCache (Open Symphony Cache), Swarm Cache, and JBoss Tree Cache. Each cache has different performance, memory use, and configuration possibilities.

2.1) 2.1 EHCache (Easy Hibernate Cache) (org.hibernate.cache.EhCacheProvider)

  • It is fast.
  • lightweight.
  • Easy-to-use.
  • Supports read-only and read/write caching.
  • Supports memory-based and disk-based caching.

Does not support clustering.

2.2)OSCache (Open Symphony Cache) (org.hibernate.cache.OSCacheProvider)

  • It is a powerful .
  • flexible package
  • supports read-only and read/write caching.
  • Supports memory- based and disk-based caching.
  • Provides basic support for clustering via either JavaGroups or JMS.

2.3)SwarmCache (org.hibernate.cache.SwarmCacheProvider)

  • is a cluster-based caching.
  • supports read-only or nonstrict read/write caching .
  • appropriate for applications those have more read operations than write operations.

2.4)JBoss TreeCache (org.hibernate.cache.TreeCacheProvider)

  • is a powerful replicated and transactional cache.

useful when we need a true transaction-capable caching architecture .

 

(3) Caching Strateties

Important thing to remembered while studying this one is none of the cache providers support all of the cache concurrency strategies.

3.1) Read-only

  • Useful for data that is read frequently but never updated.
  • It is Simple .
  • Best performer among the all.

Advantage if this one is, It is safe for using in a cluster. Here is an example for using the read-only cache strategy.

                                       
<class name="abc.mutable " mutable="true ">
<cache usage="read-only"/>
....

</class>

3.2) Read-Write

  • Used when our data needs to be updated.
  • It’s having more overhead than read-only caches.
  • When Session.close() or Session.disconnect() is called the transaction should be completed in an environment where JTA is no used.
  • It is never used if serializable transaction isolation level is required.
  • In a JTA environment, for obtaining the JTA TransactionManager we must specify the property hibernate.transaction.manager_lookup_class.
  • To use it in a cluster the cache implementation must support locking.

Here is an example for using the read-write cache stringategy.

                                       
<class name="abc.xyz" .... >
<cache usage="read-write"/>
….
<set name="yuv" ... >
<cache usage="read-write"/>
….
</set>
</class>

3.3) Nonstrict read-write

  • Needed if the application needs to update data rarely.
  • we must specify hibernate.transaction.manager_lookup_class to use this in a JTA environment .
  • The transaction is completed when Session.close() or Session.disconnect() is called In other environments (except JTA) .

Here is an example for using the nonstrict read-write cache stringategy.

                                       
<class name="abc.xyz" .... >
<cache usage=" nonstringict-read-write"/>
….
</class>

3.4) Transactional

  • It supports only transactional cache providers such as JBoss TreeCache.
  • only used in JTA environment.

(4)  Configuration

For configuring cache the hibernate.cfg.xml file is used. A typical configuration file is shown below.

<hibernate-configuration>
        <session-factory>
               ...
               <property name="hibernate.cache.provider_class">
                       org.hibernate.cache.EHCacheProvider
               </property>
               ...
        </session-factory>
</hibernate-configuration>

The name in <property> tag must be hibernate.cache.provider_class for activating second-level cache. We can use hibernate.cache.use_second_level_cache property, which allows you to activate and deactivate the second-level cache. By default, the second-level cache is activated and uses the EHCache.

(5) Advantages

5.1) Performance

Hibernate provides some metrics for measuring the performance of caching, which are all described in the Statistics interface API, in three categories:

  • Metrics related to the general Session usage.
  • Metrics related to the entities, collections, queries, and cache as a whole.
  • Detailed metrics related to a particular entity, collection, query or cache region.

5.2) About Caching

  • All objects those are passed to methods save(), update() or saveOrUpdate() or those you get from load(), get(), list(), iterate() or scroll() will be saved into cache.
  • flush() is used to synchronize the object with database and evict() is used to delete it from cache.
  • contains() used to find whether the object belongs to the cache or not.
  • Session.clear() used to delete all objects from the cache .
  • Suppose the query wants to force a refresh of its query cache region, we should call Query.setCacheMode(CacheMode.REFRESH).

(6) Conclusion

Caching is good one and hibernate found a good way to implement it for improving its performance in web applications especially when more database traffic occurs. If we implement it very correctly, we will get our applications to be running at their maximum capacities. I will cover more about the caching implementations in my coming articles. Try to get full coding guidelines before going to implement this.