Spring Data JPA and Hibernate Interview Questions

In this tutorial series, we will discuss most important concepts which may be asked in interviews.

1.What Is Java Persistence API?

The Java Persistence API provides a specification for persisting, reading, and managing data from your Java object to relational tables in the database.
Mapping Java objects to database tables and vice versa is called Object-relational mapping (ORM) .

JPA is a specification and several implementations are available. Popular implementations are Hibernate, Spring Data JPA , Apache OpenJPA and
Toplink .

2. What is Hibernate Framework?

Hibernate ORM (Hibernate in short) is an object-relational mapping tool for the Java programming language. It provides a framework for mapping an object-oriented domain model to a relational database. Hibernate handles object-relational impedance mismatch problems by replacing direct, persistent database accesses with high-level object handling functions.

Hibernate’s primary feature is mapping from Java classes to database tables, and mapping from Java data types to SQL data types. Hibernate also provides data query and retrieval facilities. It generates SQL calls and relieves the developer from the manual handling and object conversion of the result set.

Hibernate provides reference implementation of Java Persistence API, that makes it a great choice as ORM tool with benefits of loose coupling. We can use Hibernate persistence API for CRUD operations. Hibernate framework provide option to map plain old java objects to traditional database tables with the use of JPA annotations as well as XML based configuration.

3. What are the benefits of using JPA framework in persistence layer?
  • Elimination of boilerplate code which earlier being added for JDBC.
  • These frameworks(Spring Data JPA and Hibernate) can be easily integrated into the applications.
  • Provides support for caching thus improves the performance.
  • It provides support for Native and Named queries so that we can write dynamic and complex queries.
  • Easily configurable using XML or JPA annotations.
  • Provides support for HQL same as SQL which has better performance.
4. What is the difference between SessionFactory and EntityManager ?

EntityManager interface is similar to sessionFactory in hibernate. EntityManager is under javax.persistance package but session and sessionFactory under org.hibernate.Session/sessionFactory package.

Entity manager is JPA specific and session/sessionFactory are hibernate specific.

EntityManager

@PersistenceContext
EntityManager entityManager;

public List<MyEntity> findById() {
  return entityManager
     .createQuery("from MyEntity where apples=7", MyEntity.class)
     .getResultList();
}

SessionFactory

@Autowired
SessionFactory sessionFactory;

public List<MyEntity> findById() {
  Session session = sessionFactory.getCurrentSession();
  List<?> result = session.createQuery("from MyEntity where id=1")
      .list();
  @SuppressWarnings("unchecked")
  List<MyEntity> resultCasted = (List<MyEntity>) result;
  return resultCasted;
}

Also EntityManger looks cleaner and is also easier to test because EntityManager can be easily mocked.

5. What is hibernate configuration file?

Hibernate configuration file contains database specific configurations and used to initialize SessionFactory. We provide database credentials or JNDI resource information in the hibernate configuration xml file. Some other important parts of hibernate configuration file is Dialect information, so that hibernate knows the database type and mapping file or class details.

6. What are the annotations used JPA implementation?

@Entity – This marks class as Entity

@Table – This maps class to database table

@Id – Marks the class variable as primary key column in table

@Column – Marks it as a column in table , we can also configure name attribute defining its name in database table

@GeneratedValue – Marking a field with the @GeneratedValue annotation specifies that a value will be automatically generated for that field. This is primarily intended for primary key fields .There are below types of strategies –

GenerationType.AUTO – It is the default generation type and lets the persistence provider choose the generation strategy.

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", updatable = false, nullable = false)
private Long id;

GenerationType.IDENTITY – The GenerationType.IDENTITY is the easiest to use but not the best one from a performance point of view. It relies on an auto-incremented database column and lets the database generate a new value with each insert operation. From a database point of view, this is very efficient because the auto-increment columns are highly optimized, and it doesn’t require any additional statements.

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", updatable = false, nullable = false)
private Long id;

GenerationType.SEQUENCE – The GenerationType.SEQUENCE is my preferred way to generate primary key values and uses a database sequence to generate unique values.

If you don’t provide sequence name hibernate will provide its default sequence

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "id", updatable = false, nullable = false)
private Long id;

You can change that by referencing the name of a @SequenceGenerator in the generator attribute of the @GeneratedValue annotation. The @SequenceGenerator annotation lets you define the name of the generator, the name, and schema of the database sequence and the allocation size of the sequence.

GenerationType.TABLE – The GenerationType.TABLE gets only rarely used nowadays. It simulates a sequence by storing and updating its current value in a database table which requires the use of pessimistic locks which put all transactions into a sequential order. This slows down your application, and you should, therefore, prefer the GenerationType.SEQUENCE, if your database supports sequences, which most popular databases do

If you don’t provide sequence name hibernate will provide its default sequence

@Id
@GeneratedValue(strategy = GenerationType.TABLE)
@Column(name = "id", updatable = false, nullable = false)
private Long id;

Summary:

  1. AUTO: Hibernate selects the generation strategy based on the used dialect,
  2. IDENTITY: Hibernate relies on an auto-incremented database column to generate the primary key,
  3. SEQUENCE: Hibernate requests the primary key value from a database sequence,
  4. TABLE: Hibernate uses a database table to simulate a sequence.

package com.anup.springboot.pojo;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
/**
@author anup
*/
@Entity
@Table(name = "TODO")
public class Todo implements Serializable {
@Id
@Column(name = "ID")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "TASK_NAME")
private String taskName;
@Column(name = "TASK_DESC")
private String taskDesc;
@Column(name = "STATUS")
private String status;
public Todo() {
super();
}
public Todo(Long id, String taskName, String taskDesc, String status) {
super();
this.id = id;
this.taskName = taskName;
this.taskDesc = taskDesc;
this.status = status;
}
//Setters and Getters
} 

7. Why is it advisable to use single instance of SessionFactory across your application?

There are some key points regarding one SessionFactory Object per application : –

1.Single Data Store : – It is single data store for your whole application. Although you can have multiple SessionFactory but each SessionFactory will have one different database associated with it.SessionFactory is a heavy weight object.

2.Thread Safe : – SessionFactory is thread safe so due to this feature many thread can access the SessionFactory.

3.Immutable : – Once the SessionFactory’s object is created you can not change or set the values of Session Facoty. Its internal state is set at the time of creation.

4.Singleton : – SessionFactory is built at the time of application startup and it follows the singleton design pattern.

Because creation of a SessionFactory is an extremely expensive process which involves parsing hibernate configuration/mapping properties and creating database connection pool .Creating a database connection pool requires establishing database connections (i.e creating Connection objects) which has overhead due to the time taken to locate the DB server , establish a communication channel and exchange information to do authentication.

So if you create a SessionFactory for every request , it implies that you are not using database connection pool to serve your request .You have to setup a new connection by the above overheaded process for every request instead of just getting the opened connection from the database connection pool.

8. What is Session Object in Hibernate and when its used?

We can create the Session object using SessionFactory. We create the session by calling openSession() method on factory object.

Session session = factory.openSession(); 

OR

Session session = factory.getCurrentSession(); 

Using this session object we can perform save,update,delete,get operations on the entities.

9. What is the difference between openSession and getCurrentSession methods?

Hibernate SessionFactory openSession() method always opens a new session. We should close this session object once we are done with all the database operations.

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 don’t need to close it. Once the session factory is closed, this session object gets closed.

10. What are the possible states of entity bean?

Entity bean can have below possible state –

  1. Transient: When ever we create a new object of Entity bean then we can say that is in Transient state,At that time any modification in the object state does not effect on database.
  2. Persistent: When ever the Object of entity bean associated with session we can say that is in persistent state, if any change in the object state , then that modification effects in database.
  3. Detached :When ever the object is removed from session then it enters in to detached state.Any modification on detached state object , does not effect in database.

/**
 * @author anup
 */
@Entity
@Table(name = "TODO")
public class Todo implements Serializable {
    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "TASK_NAME")
    private String taskName;
    @Column(name = "TASK_DESC")
    private String taskDesc;
    @Column(name = "STATUS")
    private String status;

    public Todo() {
        super();
    }

    public Todo(Long id, String taskName, String taskDesc, String status) {
        super();
        this.id = id;
        this.taskName = taskName;
        this.taskDesc = taskDesc;
        this.status = status;
    }

    //Setters and Getters
}
class StateTest
{
    public static void main(String[]args)
    {
        SessionnFactory factory=new Configuration().configure("hibewrnate.cfg.xml").buildSessionFactpry();
        Sessiion session1=factory.openSession();
        Todo e1=new Todo(1l, "Wakeup", "Wake up at 7AM", "DONE"); //Entity bean in Transient sate.
        
        Transaction tx1=session1.beginTransaction();
        session1.save(e1); //Entity bean in persistent state
        e1.setTaskName("Running"); //Will effect in db
        tx1.commit();
        session1.close();
        //Now e1 in ditached state
        e1.setStream("Webservices"); //Will not effect in db

    }
}

11. Why do we need to have no-arg constructor entity bean?

The implementation of the default no arg constructor, is not mandatory . Only case where you need to specify it is when you declare another parametrized constructor. In Hibernate, no-arg constructor is used to loading database entities via Reflection .

12. Can you make entity class as final?

You can make an Hibernate Entity class final, but that’s not a good practice.
Generally, persistence providers make proxies of objects using some library like CGLIB or javassist. These proxies are creating runtime subclasses of the entities. That’s why they should not be final.

Since Hibernate uses proxy pattern for performance improvement, so 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.

13. What is the difference between get() and load() and when to use what ?

If no row with the given identifier value exists in the database, get() returns null. The load() method throws an ObjectNotFoundException. It’s your choice what error-handling you prefer.
More important, the load() method may return a proxy, a placeholder, without hitting the database. The get() method on the other hand never returns a proxy, it always hits the database.

  • Use get() when you want to load an object
  • Use load() when you need to obtain a reference to the object without issuing extra SQL queries, for example, to create a relationship with another object.

 public void savePost(long authorId, String text) {   
Post p = new Post();     
p.setText(text);   
// No SELECT query here. 
// Existence of Author is ensured by foreign key constraint on Post.     p.setAuthor(s.load(Author.class, authorId));     
s.save(p); } 

14. What is the first level cache in hibernate?

Hibernate by default provides first level cache. It caches the database objects i.e. entities to reduce number of queries made to database in a single transaction.

It is associated with Session object .As we create session object on demand from session factory and it is lost, once the session is closed. So first level cache is available till the time that session object is alive. It is available to session object only and is not accessible to any other session object in any other part of application.

Case 1: Below example shows the role of first level cache while retrieving Department object twice –

//Open the hibernate session
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
 
//fetch the department entity from database first time
Department department = (Department) session.load(DepartmentEntity.class, new Integer(1));
System.out.println(department.getName());
 
//fetch the department entity again
department = (Department) session.load(Department.class, new Integer(1));
System.out.println(department.getName());
 
session.getTransaction().commit();
HibernateUtil.shutdown();
 
Output:
 
Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
COMPUTER
COMPUTER

Its quiet clear from the logs that when we get the object second time , its doesn’t hit the database. Object is cached on the first load itself.

Case 2: Below example shows the role of first level cache while retrieving Department object from multiple sessions –

//Open the hibernate session
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();

Session sessionDummy = HibernateUtil.getSessionFactory().openSession();
sessionDummy.beginTransaction();
 
//fetch the department entity from database first time
Department department = (Department) session.load(Department.class, new Integer(1));
System.out.println(department.getName());
 
//fetch the department entity again
department = (Department) session.load(Department.class, new Integer(1));
System.out.println(department.getName());
 
//fetch the department entity again
department = (Department) sessionDummy.load(Department.class, new Integer(1));
System.out.println(department.getName());

session.getTransaction().commit();
sessionDummy.getTransaction().commit();
HibernateUtil.shutdown();
 
Output:
 
Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
COMPUTER
COMPUTER
Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
COMPUTER

From the logs its quiet clear that when we load the object second time in single session, its doesn’t hit the database. But when we load the Object in different session, it hits the database again.

Remove Objects from First Level Cache –

Though we can not disable the first level cache in hibernate, but we can certainly remove some of objects from it when needed. This is done using two methods :

  • evict()
  • clear()

Here evict() is used to remove a particular object from cache associated with session, and clear() method is used to remove all cached objects associated with session. 

15. What is the second level cache in hibernate ?

Second level cache works on SesionFactory level. So irrespective of multiple sessions , second level cache will cache the data across all sessions.

This is apart from first level cache which is available to be used globally in session factory scope. Once session factory is closed, all cache associated with it die and cache manager also closed down.

There are multiple implementations of second level cache provided by many vendors like –

  1. EH Cache
  2. OS Cache
  3. Swarm Cache
  4. JBoss Cache

We need to add below dependency in maven –

<dependency>  
    <groupId>net.sf.ehcache</groupId>  
    <artifactId>ehcache</artifactId>  
    <version>2.10.3</version>  
</dependency>  

Also Entity class needs to be annotated with below annotations –

package com.myjavablog;
import javax.persistence.*;  
import org.hibernate.annotations.Cache;  
import org.hibernate.annotations.CacheConcurrencyStrategy;  
@Entity  
@Table(name="TODO")  
@Cacheable  
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY)  
public class Todo implements Serializable {
   
}

Hibernate Configuration file hibernate.cfg.xml

<?xml version='1.0' encoding='UTF-8'?>    
<!DOCTYPE hibernate-configuration PUBLIC    
          "-//Hibernate/Hibernate Configuration DTD 5.2.0//EN"    
          "http://hibernate.sourceforge.net/hibernate-configuration-5.2.0.dtd">    
    
<hibernate-configuration>    
    
    <session-factory>    
        <property name="show_sql">true</property>    
        <property name="hbm2ddl.auto">update</property>    
        <property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>    
        <property name="connection.url">jdbc:oracle:thin:@localhost:1521:xe</property>    
        <property name="connection.username">system</property>    
        <property name="connection.password">jtp</property>    
        <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>    
         
         <property name="cache.use_second_level_cache">true</property>   
         <property name="cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>  
         <mapping class="com.myjavablog.Todo"/>  
    </session-factory>    
</hibernate-configuration>  

Class to access the entity –

//Open the hibernate session
Session session1 = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();

Session session2 = HibernateUtil.getSessionFactory().openSession();
sessionDummy.beginTransaction();
 
//fetch the department entity from database first time
Department department = (Department) session1.load(Department.class, new Integer(1));
System.out.println(department.getName());
 
//fetch the department entity again
department = (Department) session2.load(Department.class, new Integer(1));
System.out.println(department.getName());

session1.getTransaction().commit();
session2.getTransaction().commit();
HibernateUtil.shutdown();
 
Output:
 
Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
COMPUTER
COMPUTER

16. What is the difference between save() and persist() methods ?

Save()

  1. Returns generated Id after saving. Its Serializable return type.
  2. Saves the value to DB immediately and keeps track of the entity until the end of the session(I have tried to change the entity values outside of the transaction, it does not show any effect when session commits)
  3. save the changes to the db outside of the transaction.
  4. Assigns the generated id to the entity you are persisting
  5. Session.save() for a detached object will create a new row in the table.

Persist()

  1. Does not returns generated Id after saving. Its void return type.
  2. Saves the value to DB immediately and keeps track of the entity until the end of the session.(I have tried to change the entity values outside of the transaction, it does not show any effect when session commits)
  3. Does not save the changes to the db outside of the transaction.
  4. Assigns the generated id to the entity you are persisting
  5. session.persist() for a detached object will throw PersistentObjectException as it is not allowed.
17. What is the relationship and how to implement it?

Two entities can have relationship between them . In relational database, two tables are related to by foreign key .This can be implemented in hibernate through below annotations.

18.What is cascading and what are different types of cascading?

Two entities are related to each other via a foreign key relationship.
When we have relationship between entities, then we need to define how the different operations will affect the other entity. In hibernate we use CASCADE operations to handle this.

@Entity
@Table(name = "STUDENT")
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column
    private String name;
    @Column
    private int mobile;
    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "DEPT_ID")
    private Department department;

Here Many students can be a part of single department . DEPT_ID is foreign key in Student table is associated to ID in Department table.

Commonly used cascading types as defined in CascadeType enum are:

  1. None: No Cascading, it’s not a type but when we don’t define any cascading then no operations in parent affects the child.
  2. ALL: Cascades save, delete, update, evict, lock, replicate, merge, persist. Basically all operations.
  3. SAVE_UPDATE: Cascades save and update, available only in hibernate.
  4. DELETE: Corresponds to the Hibernate native DELETE action, only in hibernate.
  5. DETATCH, MERGE, PERSIST, REFRESH and REMOVE – for similar operations
  6. LOCK: Corresponds to the Hibernate native LOCK action.
  7. REPLICATE: Corresponds to the Hibernate native REPLICATE action.
19. How to log the queries generated by hibernate on console?

When we call methods like save,update,delete,get on entities in session then queries gets generated on backend by hibernate. We can see these queries on console by just adding below line to hibernate configuration file –

<property name="hibernate.show_sql">true</property>

20. What is Native SQL query in hibernate?

You can write your own queries and execute them against the database. For Hibernate Native SQL Query, we use Session.createSQLQuery(String query) to create the SQLQuery object and execute it.
Native SQL Query comes handy when we want to execute database specific queries that are not supported by Hibernate API such as query hints or the CONNECT keyword in Oracle Database.

21. What is Named Native SQL query in hibernate?

Hibernate provides Named Query that we can define at a central location and use them anywhere in the code. We can create named queries for both HQL and Native SQL.

Hibernate Named Queries can be defined in Hibernate mapping files or through the use of JPA annotations @NamedQuery and @NamedNativeQuery.

1 thought on “Spring Data JPA and Hibernate Interview Questions”

  1. I have noticed you don’t monetize 162.32, don’t waste your traffic, you
    can earn additional bucks every month with new monetization method.
    This is the best adsense alternative for any type of website (they approve all websites),
    for more details simply search in gooogle: murgrabia’s tools

    Reply

Leave a Comment

Bitnami