Hibernate Interview Questions for experienced professionals – Part 2

Hibernate Interview Questions for experienced professionals

 
Hibernate Interview Questions for experienced professionals- Part 2
Hibernate Interview Questions for experienced professionals- Part 2

1. How to implement Inheritance in hibernate?

1. InheritanceType.SINGLE_TABLE
Here hibernate will create a single table with extra column to save the object type. There are 2 ways to implement this strategy. One with default implementation and another with custom values.
A. With Default Implementation
Keeping only as entity will create the single table with an extra field as DTYPE(Descriminator Type), which is used to identify the child node. Here it will insert the class name as DTYPE value as default.

@Entity(name="Vehicale")
public class Vehicle 

@Entity
public class TwoWheeler extends Vehicle { 

@Entity
public class FourWheeler extends Vehicle {

Hibernate executes below queries to create the table structure
Hibernate: create table Vehicale (DTYPE varchar(31) not null, vehicalId integer not null auto_increment, vehicleName varchar(255), steeringHandle varchar(255), SteeringWheel varchar(255), primary key (vehicalId))
Hibernate: insert into Vehicale (vehicleName, SteeringWheel, DTYPE) values (?, ?, ‘FourWheeler’)
Hibernate: insert into Vehicale (vehicleName, steeringHandle, DTYPE) values (?, ?, ‘TwoWheeler’)

B. With custom values
It has created the DTYPE column with VEHICAL_TYPE name.

@Entity(name="Vehicle")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) // by default its single_type
@DiscriminatorValue("Vehical1")
@DiscriminatorColumn(
  name="VEHICAL_TYPE", // Its the DTYPE column name
  discriminatorType = DiscriminatorType.STRING // defines the data type of the Discriminator column
)
public class Vehicle
@Entity
@DiscriminatorValue("Bike")*/

public class TwoWheeler extends Vehicle {
@Entity
@DiscriminatorValue("Car")*/

public class FourWheeler extends Vehicle {

Hibernate executes below queries to create the table structure
Hibernate: create table Vehicale (VEHICAL_TYPE varchar(31) not null, vehicalId integer not null auto_increment, vehicleName varchar(255), steeringHandle varchar(255), SteeringWheel varchar(255), primary key (vehicalId))
Hibernate: insert into Vehicale (vehicleName, SteeringWheel, VEHICAL_TYPE) values (?, ?, ‘Car’)
Hibernate: insert into Vehicale (vehicleName, steeringHandle, VEHICAL_TYPE) values (?, ?, ‘Bike’)

2. InheritanceType.TABLE_PER_CLASS
Here it will create the tables for child and adds all the columns of parent vehicle to each child.

Hibernate executes below queries to create the table structure
Hibernate: create table FourWheeler (vehicalId integer not null, gear varchar(255), vehicleName varchar(255), SteeringWheel varchar(255), primary key (vehicalId))
Hibernate: create table TwoWheeler (vehicalId integer not null, gear varchar(255), vehicleName varchar(255), steeringHandle varchar(255), primary key (vehicalId))
Hibernate: create table Vehicle (vehicalId integer not null, gear varchar(255), vehicleName varchar(255), primary key (vehicalId))

Hibernate: create table hibernate_sequence (next_val bigint)
Hibernate: insert into hibernate_sequence values ( 1 )

Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: insert into FourWheeler (gear, vehicleName, SteeringWheel, vehicalId) values (?, ?, ?, ?)
Hibernate: insert into TwoWheeler (gear, vehicleName, steeringHandle, vehicalId) values (?, ?, ?, ?)
Hibernate: insert into Vehicle (gear, vehicleName, vehicalId) values (?, ?, ?)

3. InheritanceType.JOINED
Here it will save the child to child specific table and the inherited data to the parent  table.

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public class Vehicle 

@Entity
public class TwoWheeler extends Vehicle { 

@Entity
public class FourWheeler extends Vehicle {

Hibernate executes below queries to create the table structure
Hibernate: create table hibernate_sequence (next_val bigint)
Hibernate: insert into hibernate_sequence values ( 1 )
Hibernate: create table TwoWheeler (steeringHandle varchar(255), vehicalId integer not null, primary key (vehicalId))
Hibernate: create table Vehicle (vehicalId integer not null, gear varchar(255), vehicleName varchar(255), primary key (vehicalId))
Hibernate: alter table FourWheeler add constraint FKht0cqtqrdif46n5kivktu9yxq foreign key (vehicalId) references Vehicle (vehicalId)
Hibernate: alter table TwoWheeler add constraint FK70afs1vc9sklp9vc34cpj83lo foreign key (vehicalId) references Vehicle (vehicalId)

Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?

Hibernate: insert into Vehicle (gear, vehicleName, vehicalId) values (?, ?, ?)
Hibernate: insert into FourWheeler (SteeringWheel, vehicalId) values (?, ?)
Hibernate: insert into Vehicle (gear, vehicleName, vehicalId) values (?, ?, ?)
Hibernate: insert into TwoWheeler (steeringHandle, vehicalId) values (?, ?)
Hibernate: insert into Vehicle (gear, vehicleName, vehicalId) values (?, ?, ?)

2. How to implement the database relationship types in hibernate?

1. One to One Mapping in Hibernate

We can implement the one to one mapping into three ways.
A. Foreign Key Association
Here hibernate will create a new column to store the foreign key.

@Entity
@Table(name="stock")
public class OTO_Stock 
{
    @OneToOne(cascade = CascadeType.ALL, fetch=FetchType=LAZY)
    @JoinColumn(name="detailsId")
    private OTO_StockDetails details; @Entity
@Table(name="stock_details")
public class OTO_StockDetails 
{

    @OneToOne(mappedBy="details")
   private OTO_Stock stock;

B. Shared primary key
Here same key is used for both the tables. Here even having the fetch type lazy will fetch the corresponding object at eager.

@Entity
@Table(name="stock")
public class OTO_Stock 
{
    @OneToOne(cascade = CascadeType.ALL, fetch=FetchType=LAZY)
    @PrimaryKeyJoinColumn
    private OTO_StockDetails details; @Entity
@Table(name="stock_details")
public class OTO_StockDetails 
{
    @OneToOne(mappedBy="details")
   private OTO_Stock stock;

C. Join Table
Creates new table to hold the entries, it can be also used to hold the one to many relationships.

@Entity
@Table(name="stock")
public class OTO_Stock 
{
@OneToOne(cascade = CascadeType.ALL)
@JoinTable( joinColumns = @JoinColumn(name="stockid"), 
inverseJoinColumns = @JoinColumn(name="detailsId"), name="Stock_Details_Mapping")
private OTO_StockDetails details;

@Entity
@Table(name="stock_details")
public class OTO_StockDetails 
{
@OneToOne(mappedBy="details", fetch=FetchType.LAZY)
@JoinTable( inverseJoinColumns= @JoinColumn(name="stockid"), joinColumns = @JoinColumn(name="detailsId"), name="Stock_Details_Mapping")
  private OTO_Stock stock;

2. One to Many Mapping in Hibernate

@Entity
@Table(name = "OTM_Employee", catalog = "sampledb")
public class OTM_Employee
 {
@OneToMany(mappedBy="employee" ,cascade = CascadeType.ALL, fetch=FetchType.LAZY)
private Set<OTM_Account> account; @Entity
@Table(name = "OTM_Account", catalog = "sampledb")
public final class OTM_Account
{
@ManyToOne(cascade= CascadeType.ALL)
@JoinColumn(name="employee_id")
private OTM_Employee employee;

3. Many to Many Mapping in Hibernate

@Entity
@Table(name="mtm_class", catalog="sampledb")
public class MTM_Class
{
@ManyToMany(mappedBy="class1")
 private Set<MTM_Student> student; @Entity
@Table(name="mtm_student", catalog="sampledb")
public class MTM_Student {
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name="mtm_student_class_mapping", joinColumns={@JoinColumn(referencedColumnName="student_id")},
inverseJoinColumns={@JoinColumn(referencedColumnName="class_id")})
 private Set<MTM_Class> class1;

3. How to fetch specific columns from the table?

Hibernate provides Projection to fetch specific columns from the database.
criteria.setProjection() – we can pass single Projection Object or ProjectionList as param to this method. This list will have the column names to be fetch.

Session session = factory.openSession();
 
        System.out.println("Reading Partial Entity with One Projection object ");
 
        Criteria criteria = session.createCriteria(Employee.class);
        Projection projection = Projections.property("salary");
        criteria.setProjection(projection);
        List list = criteria.list(); //We will get list if we pass single Projection
        Iterator it = list.iterator();
 
        while (it.hasNext()) {
            Integer sal = (Integer) it.next();
            System.out.println("Employee Salary : " + sal);
        }
         
        System.out.println("Reading Partial Entity with multiple Projection objects ");
         
        Criteria crit2 = session.createCriteria(Employee.class);
        Projection projection1 = Projections.property("salary");
        Projection projection2 = Projections.property("departmentId");
        Projection projection3 = Projections.property("employeeName");
         
        ProjectionList pList = Projections.projectionList();
        pList.add(projection1);
        pList.add(projection2);
        pList.add(projection3);
        crit2.setProjection(pList);
         
        List list2 = crit2.list();
 
        Iterator it2 = list2.iterator();
 
        while (it2.hasNext()) {
            Object[] obj = (Object[]) it2.next(); //We will get Object[] if we pass multiple Projection
            System.out.println("Salary : " + obj[0]+" DeptId : "+obj[1]+" empName : "+obj[2]);
        }
    }

4. How to configure Second level cache in hibernate?

https://www.baeldung.com/hibernate-second-level-cache

5. What are the disadvantages of Query and Second level cache?

1 – Cache limitations when used in conjunction with @Inheritance
It is currently not possible to specify different caching policies for different subclasses of the same parent entity.
For example this will not work:

@Entity
@Inheritance
@Cache(CacheConcurrencyStrategy.READ_ONLY)
public class BaseEntity {
    ...
}
@Entity
@Cache(CacheConcurrencyStrategy.READ_WRITE)
public class SomeReadWriteEntity extends BaseEntity {
    ...
}
@Entity
@Cache(CacheConcurrencyStrategy.TRANSACTIONAL)
public class SomeTransactionalEntity extends BaseEntity {
    ...
}

In this case only the @Cache annotation of the parent class is considered, and all concrete entities have READ_ONLY concurrency strategy.

2 – Query cache worsens performance causing a high volume of queries
If a query has cached results, it returns a list of entity Id’s, that is then resolved against the second level cache. If the entities with those Ids where not configured as cacheable or if they have expired, then a select will hit the database per entity Id.
For example if a cached query returned 1000 entity Ids, and non of those entities where cached in the second level cache, then 1000 selects by Id will be issued against the database.
The solution to this problem is to configure query results expiration to be aligned with the expiration of the entities returned by the query.

Based on this, we need to create the appropriate constructor in the entity class, which will return the User object reference with just the required properties that we are retrieving.

public User() { }
   
public User(int id, String username) {
this.username = username;
this.id = id;
}

With our constructor-based HQL implementation, when the query is executed, all instances returned by your query are in transient state, which means that the query doesn’t return persistent entity instances and Hibernate no more adds any persistent object to the persistence context cache. This means that no object will be watched for dirty state either.

6. How hibernate identifies which objects needs to be updated in the transaction?

Automatic Dirty – It calls update statement automatically on the objects that are modified in a transaction.
Hibernate uses a strategy called inspection, which is basically this: when an object is loaded from the database a snapshot of it is kept in memory. When the session is flushed Hibernate compares the stored snapshot with the current state. If they differ the object is marked as dirty and a suitable SQL command is enqueued. If the object is still transient then it is always dirty.

7. What is difference between sorted collection and ordered collection, which one is better?

When we use Collection API sorting algorithms to sort a collection, it’s called sorted list. For small collections, it’s not much of an overhead but for larger collections it can lead to slow performance and OutOfMemory errors. Also the entity beans should implement Comparable or Comparator interface for it to work, read more at java object list sorting.
If we are using Hibernate framework to load collection data from database, we can use it’s Criteria API to use “order by” clause to get ordered list. Below code snippet shows you how to get it.

List<Employee> empList = session.createCriteria(Employee.class)
      .addOrder(Order.desc("id")).list();

Ordered list is better than sorted list because the actual sorting is done at database level, that is fast and doesn’t cause memory issues.

8. Why we should not make Entity Class final?

Hibernate use proxy classes for lazy loading of data, only when it’s needed. This is done by extending the entity bean, if the entity bean will be final then lazy loading will not be possible, hence low performance.

9. What will happen if we don’t have no-args constructor in Entity bean?

Hibernate uses Reflection API to create instance of Entity beans, usually when you call get() or load() methods. The method Class.newInstance() is used for this and it requires no-args constructor. So if you won’t have no-args constructor in entity beans, hibernate will fail to instantiate it and you will getHibernateException.

10. What are the benefits of Named SQL Query?

Hibernate Named Query helps us in grouping queries at a central location rather than letting them scattered all over the code.
Hibernate Named Query syntax is checked when the hibernate session factory is created, thus making the application fail fast in case of any error in the named queries.
Hibernate Named Query is global, means once defined it can be used throughout the application.
However one of the major disadvantage of Named query is that it’s hard to debug, because we need to find out the location where it’s defined.

11. What is Hibernate Proxy and how it helps in lazy loading?

Hibernate uses proxy object to support lazy loading. Basically when you load data from tables, hibernate doesn’t load all the mapped objects. As soon as you reference a child or lookup object via getter methods, if the linked entity is not in the session cache, then the proxy code will go to the database and load the linked object. It uses javassist to effectively and dynamically generate sub-classed implementations of your entity objects.
Javassist – Java Programming Assistant) makes Java bytecode manipulation simple. It is a class library for editing bytecodes in Java; it enables Java programs to define a new class at runtime and to modify a class file when the JVM loads it.

12. Which design patterns are used in Hibernate framework?

Some of the design patterns used in Hibernate Framework are:
Domain Model Pattern – An object model of the domain that incorporates both behavior and data.
Data Mapper – A layer of Mappers that moves data between objects and a database while keeping them independent of each other and the mapper itself.
Proxy Pattern for lazy loading
Factory pattern in SessionFactory