Hibernate Interview Questions Hibernate Interview Questions

Page content

List of frequently asked hibernate interview questions. Keep following this post for regular updates.

What are the key classes and interfaces in Hibernate?

  1. Configuration

    Configuration configuration = new Configuration();
    
    // Hibernate settings equivalent to hibernate.cfg.xml's properties
    Properties settings = new Properties();
    settings.put(Environment.DRIVER, "com.mysql.cj.jdbc.Driver");
    settings.put(Environment.URL, "jdbc:mysql://localhost:3306/hibernate_db?useSSL=false");
    settings.put(Environment.USER, "root");
    settings.put(Environment.PASS, "root");
    settings.put(Environment.DIALECT, "org.hibernate.dialect.MySQL5Dialect");
    settings.put(Environment.SHOW_SQL, "true");
    settings.put(Environment.HBM2DDL_AUTO, "create-drop");
    
    configuration.setProperties(settings);
    
  2. ServiceRegistry

    ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
        .applySettings(configuration.getProperties()).build();
    
  3. SessionFactory provides an instance of Session. It is a factory class that gives the Session objects based on the configuration parameters in order to establish the connection to the database. As a good practice, the application generally has a single instance of SessionFactory. The internal state of a SessionFactory which includes metadata about ORM is immutable, i.e once the instance is created, it cannot be changed.

    SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
    
  4. Session is an object that maintains the connection between Java object application and database. Session also has methods for storing, retrieving, modifying or deleting data from database using methods like persist(), load(), get(), update(), delete(), etc. Additionally, It has factory methods to return Query, Criteria, and Transaction objects.

    Session session = sessionFactory.openSession();
    
  5. Query

    String hql = "FROM Employee";
    Query query = session.createQuery(hql);
    List results = query.list();
    
  6. Criteria

    Criteria criteria = session.createCriteria(Employee.class);
    // To get records having salary more than 2000
    criteria.add(Restrictions.gt("salary", 2000));
    List results = criteria.list();
    
  7. Transaction

    Session session = sessionFactory.openSession();
    Transaction transaction;
    try {
        transaction = session.beginTransaction();
        //do some work
        ...
        transaction.commit();
    }
    catch (Exception e) {
        if (transaction!=null) transaction.rollback();
        throw e;
    }
    finally {
        session.close();
    }
    

Difference between first and second level cache?

Hibernate has 2 cache types. First level and second level cache for which the difference is given below:

First Level Cache Second Level Cache
This is local to the Session object and cannot be shared between multiple sessions. This cache is maintained at the SessionFactory level and shared among all sessions in Hibernate.
This cache is enabled by default and there is no way to disable it. This is disabled by default, but we can enable it through configuration.
The first level cache is available only until the session is open, once the session is closed, the first level cache is destroyed. The second-level cache is available through the application’s life cycle, it is only destroyed and recreated when an application is restarted.

If an entity or object is loaded by calling the get() method then Hibernate first checked the first level cache, if it doesn’t find the object then it goes to the second level cache if configured. If the object is not found then it finally goes to the database and returns the object, if there is no corresponding row in the table then it returns null.

Difference between save() and saveOrUpdate() methods in hibernate session?

Both the methods save records to the table in the database in case there are no records with the primary key in the table. However, the main differences between these two are listed below:

save() saveOrUpdate()
Session.save() generates a new identifier and INSERT record into a database Session.saveOrUpdate() can either INSERT or UPDATE based upon existence of a record.
The insertion fails if the primary key already exists in the table. In case the primary key already exists, then the record is updated.
The return type is Serializable which is the newly generated identifier id value as a Serializable object. The return type of the saveOrUpdate() method is void.
This method is used to bring only a transient object to a persistent state. This method can bring both transient (new) and detached (existing) objects into a persistent state. It is often used to re-attach a detached object into a Session

Clearly, saveOrUpdate() is more flexible in terms of use but it involves extra processing to find out whether a record already exists in the table or not.

Difference between get() and load() in hibernate session?

These are the methods to get data from the database. The primary differences between get and load in Hibernate are given below:

get() load()
This method gets the data from the database as soon as it is called. This method returns a proxy object and loads the data only when it is required.
The database is hit every time the method is called. The database is hit only when it is really needed and this is called Lazy Loading which makes the method better.
The method returns null if the object is not found. The method throws ObjectNotFoundException if the object is not found.
This method should be used if we are unsure about the existence of data in the database. This method is to be used when we know for sure that the data is present in the database.

What is N+1 problem in Hibernate and how to solve?

The N+1 query problem is said to occur when an ORM, like hibernate, executes 1 query to retrieve the parent entity and N queries to retrieve the child entities. It happens due the lazy loading and on-demand fetching strategy of Hibernate.

Let’s take an example where one user can have many addresses.

@Entity
@Table(name = "user")
public class User {

	@Id
	private String id;

	@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "user")
	private List<Address> addresses;
}

@Entity
@Table(name = "address")
public class Address {
	@Id
	private String id;

	@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
	@JoinColumn(name = "user_id", referencedColumnName = "id")
	private User User;

}
String hql = "FROM User";
Query query = session.createQuery(hql);
List<User> users = query.list();

To fetch a list of users, it will fire 1 query to load all users from user table and then subsequently fire N queries to load list of addresses for each user from address table, ends up executing N+1 queries

Solve N+1

Some of the strategies followed for solving the N+1 SELECT problem are:-

  1. @EntityGraph provides a way to formulate better performing queries by defining which entities need to be retrieved from the database using SQL JOINS.
  2. Another way to use @BatchSize on lazy association to fetch records in batches, which helps us to reduce the problem of N+1 to (N/K) + 1 where K refers to the size of the batch.
  3. As last resort, try to avoid or disable lazy loading altogether.