Friday, 15 June 2018

Hibernate Query Language (HQL) with Examples

            Hibernate Query Language (HQL) is an object-oriented query language that is similar to SQL. However, instead of operating on database tables and columns, HQL works with persistent entities and their properties. HQL is a superset of the Java Persistence Query Language (JPQL). Every JPQL query is a valid HQL query, but not every HQL query is valid JPQL.

HQL has its own syntax and grammar. HQL queries are written as strings, which Hibernate translates into SQL queries before executing them against the database. Hibernate also provides APIs that allow you to execute native SQL queries directly when needed.

HQL keywords such as SELECT, FROM, and WHERE are case-insensitive. However, entity names, property names, and aliases are case-sensitive and must match the names defined in your entity classes.

Advantages:--

  • Instead of returning plain data, HQL queries return the results as entity objects or tuples of objects that can be accessed, processed, and manipulated directly in your application. This eliminates the need to manually create and populate objects from the database result set.

  • Compared to SQL, HQL provides several advanced features, such as pagination, fetch joins, dynamic fetching, and object-oriented querying, making it easier to work with persistent entities.

Examples:

I have a given one example student entity, contains fields id, name and age as below,

Student.java,

package com.adnblog;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "student")
public class Student{
    
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      @Column(name = "student_id")
      private Integer id;
     
      @Column(name = "student_name")
      private String name;
     
      @Column(name="student_age")
      private Integer age;
     
      public Integer getId() {
           return id;
      }
 
      public void setId(Integer id) {
           this.id = id;
      }
 
      public String getName() {
           return name;
      }
 
      public void setName(String name) {
           this.name = name;
      }
 
      public Integer getAge() {
           return age;
      }
 
      public void setAge(Integer age) {
            this.age = age;
      }   
}


  • HQL SELECT Query Example:--
The below query is to select the student where id is 121.


Query query = session.createQuery("from Student where id= :id");
query.setParameter("id", "121");
List list = query.list();

Equivalent sql query is,

Select * from student where student_id = 121;

The above query is same as SQL Query but in this we can use entity name as table name and field name as column name.

  • HQL UPDATE Query Example:-
The below query is to update the student name where id is 121.

Query query = session.createQuery("update Student set name= :name" +
        " where id= :id");
query.setParameter("name", "Mahesh");
query.setParameter("id", 121);
int result = query.executeUpdate();

Equivalent sql query is,

UPDATE student SET student_name = 'Mahesh'
          WHERE student_id= 121;


  • HQL DELETE Query Example:-

The below HQL query is to delete the Student from student table where id is 121.

Query query = session.createQuery("delete Student where id= :id");
query.setParameter("id", 121);
int result = query.executeUpdate();

Equivalent SQL query is,

DELETE FROM student where student_id = 121;


  • HQL INSERT Query Example:

          HQL supports only the INSERT INTO .....  SELECT……… ; there is no chance to write
 INSERT INTO ..... VALUES, it means while writing the insert query, we need to select
values from other table, we can’t insert our own values manually.


Query query = session.createQuery("insert into Student(id, name)" +
       "select student_id, student_name from other_student_table");
int result = query.executeUpdate();

Equivalent SQL Query is,

INSERT INTO student(studnet_id, student_name) 
SELECT student_id, student_name FROM other_student_table;

Thank you for visiting blog.

Related Posts:--
1) What is a Hibernate Caching ? Explain first level and second level cache in Hibernate
2) What are different states of an entity bean in Hibernate?
3) Hibernate One to One Mapping Example - Annotation based
4) Hibernate - JPA Annotations with explanation
5) Advantages of Hibernate over JDBC
6) What are the Core Interfaces of Hibernate framework ?

Monday, 11 June 2018

Hibernate Caching: First-Level and Second-Level Cache Explained

       In the previous post, we learned about the different states of an entity in Hibernate. In this post, we will learn about the caching mechanism, including the first-level cache and second-level cache in Hibernate.

What is Caching in Hibernate?

Caching is a mechanism for storing frequently accessed objects in cache memory. The main advantage of caching is that when the same object is requested again, Hibernate retrieves it from the cache instead of querying the database. This reduces the number of round trips between the application and the database server, thereby improving the application's performance.

There are mainly two types of caching in Hibernate:

  • First-Level Cache

  • Second-Level Cache



First Level Cache:-

The first-level cache is associated with the Session object. Its scope is limited to a single Hibernate session. Once the session is closed, all cached objects are removed permanently.

The first-level cache is enabled by default and cannot be disabled. When an entity is queried for the first time within a session, Hibernate retrieves it from the database and stores it in the session's first-level cache. If the same entity is requested again within the same session, Hibernate returns it from the cache instead of executing another SQL query.

A cached entity can be removed from the session using the evict() method. If the same entity is requested again after being evicted, Hibernate will execute a database query to reload it. Similarly, the clear() method removes all entities from the session cache. After calling clear(), Hibernate will fetch entities from the database again when they are requested.

Example

In this example, we will retrieve a Department object from the database using a Hibernate session. We will retrieve the same object multiple times and observe the SQL logs to understand how the first-level cache works.

//Open the hibernate session
Session session = HibernateUtil.getSessionFactory().openSession();
session.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(second time)
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=?
IT
IT


evict() and clear() method in Hibernate:-

evict():  Removes the object from the session. This method is used to dissociate/disconnect the specified object from the session.

clear () :  When this method get called inside transaction boundry then all objects  which are currently associate with particular session will be  disconnected / clean or no longer associate with that Session instance.



Second Level Cache

             The second-level cache is associated with the SessionFactory object. It is created at the SessionFactory level and is shared across all Hibernate sessions created by that SessionFactory. When the SessionFactory is closed, the second-level cache and its associated cache manager are also destroyed.

Whenever a Hibernate session attempts to load an entity, it first checks the first-level cache (which is associated with the current session). If the entity is found there, Hibernate returns it immediately without executing a database query.

If the entity is not found in the first-level cache, Hibernate checks the second-level cache. If the entity exists in the second-level cache, it is returned and also stored in the first-level cache of the current session. This ensures that subsequent requests for the same entity within the same session are served from the first-level cache without accessing the second-level cache again.

If the entity is not found in either the first-level or second-level cache, Hibernate executes a database query to retrieve it. The retrieved entity is then stored in both the first-level cache and the second-level cache (if second-level caching is enabled for that entity) before being returned to the application.

The second-level cache is not enabled by default. Hibernate supports several cache providers that implement the second-level cache, including:

  • Ehcache

  • OSCache

  • SwarmCache

  • JBoss Cache

Each cache provider offers different features and capabilities. Hibernate supports the following cache concurrency strategies:

  • read-only – Suitable for data that never changes. It provides the best performance for read-only entities.

  • nonstrict-read-write – Supports both read and write operations but does not guarantee strong consistency. Occasional stale data may be returned.

  • read-write – Supports both read and write operations while maintaining data consistency through appropriate locking mechanisms.

  • transactional – Provides transactional cache access and is intended for environments that support JTA transactions.

Example

In the following example, we will configure and use Ehcache as the provider for Hibernate's second-level cache.

hibernate.cfg.xml

<?xml version='1.0' encoding='UTF-8'?>  
<!DOCTYPE hibernate-configuration PUBLIC  
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"  
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">  
    
<hibernate-configuration>  
  
    <session-factory>  
        <property name="show_sql">true</property>  
        <property name="hbm2ddl.auto">update</property>  
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>  
        <property name="connection.url">jdbc:mysql://localhost/sample</property>  
        <property name="connection.username">root</property>  
        <property name="connection.password">root</property>  
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>  
        
        <property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>  
        <property name="hibernate.cache.use_second_level_cache">true</property>  
       
    </session-factory>  
  
</hibernate-configuration>

SampleTest.java,

package com.adnblog;  
  
import org.hibernate.Session;  
import org.hibernate.SessionFactory;  
import org.hibernate.cfg.Configuration;  
  
public class SampleTest {  
     public static void main(String[] args) {  
          Configuration cfg=new Configuration().configure("hibernate.cfg.xml");  
          SessionFactory factory=cfg.buildSessionFactory();  
      
          Session session1=factory.openSession();  
          Student std1=(Student)session1.load(Student.class,121);  
          System.out.println(std1.getId()+" "+std1.getName());  
          session1.close();  
      
          Session session2=factory.openSession();  
          Student std2=(Student)session2.load(Student.class,121);  
          System.out.println(std2.getId()+" "+std2.getName());  
          session2.close();  
      
     }  
}  
  
Output :--  select student0_.id as id0_0, student0_.name as name0_0 from STUDENT student0_ where student0_.id = ?
                   18 Mahesh M
                   18 Mahesh M

Thank you for visiting blog.



Related Post:-
1) What are different states of an entity bean in Hibernate?
2) Hibernate One to One Mapping Example - Annotation based
3) Hibernate - JPA Annotations with explanation
4) Advantages of Hibernate over JDBC
5) What are the Core Interfaces of Hibernate framework ?
6) Spring MVC with Hibernate CRUD Example