Hibernate 5 Named Query Tutorial with Examples

In Hibernate, a named query is a JPQL or SQL expression with a predefined unchangeable query string. You can define a named query either in hibernate mapping file or in an entity class.
Basically, named queries in hibernate is a technique to group the HQL statements in a single location, and lately refer them by some name whenever the need to use them. It helps largely in code cleanup because these HQL statements are no longer scattered in whole code.
Apart from the above, below are some minor advantages of named queries:
  1. Fail fast: Their syntax is checked when the session factory is created, making the application fail fast in case of an error.
  2. Reusable: They can be accessed and used from several places which increase re-usability.
The following is an example of the definition of a named query in the JPQL/HQL:
    @NamedQuery(
            name="findAllCustomersWithName",
            query="SELECT c FROM Customer c WHERE c.name LIKE :custName"
    )
Named query definition has two important attributes:
  • name: The name attribute of a named query by which it will be located using hibernate session.
  • query: Here you give the HQL statement to get executed in the database.
Annotations @NamedQuery and @NamedQueries are used for HQL or JPQL expression whereas @NamedNativeQuery and @NamedNativeQueries are used for native SQL expression.
This tutorial shows you how to use the named queries annotations in hibernation application.

Technologies and tools used

  • Hibernate 5.3.7.Final
  • IDE - Eclipse Noen
  • Maven 3.5.3
  • JavaSE 1.8
  • MySQL - 8.0.13

Create a Simple Maven Project

Use How to Create a Simple Maven Project in Eclipse article to create simple Maven project in Eclipse IDE.

2. Project Directory Structure

The project directory structure for your reference - 

3. Add jar Dependencies to pom.xml

<project
    xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>net.javaguides.hibernate</groupId>
        <artifactId>hibernate-tutorial</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>hibernate-named-query-example</artifactId>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.13</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.3.7.Final</version>
        </dependency>
    </dependencies>
    <build>
        <sourceDirectory>src/main/java</sourceDirectory>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Create a Hibernate configuration file - Java Configuration

The HibernateUtil Java configuration file contains information about the database and mapping file.
Let's create a HibernateUtil file and write the following code in it.
package net.javaguides.hibernate.util;

import java.util.Properties;

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.service.ServiceRegistry;

import net.javaguides.hibernate.entity.Student;

public class HibernateUtil {
    private static SessionFactory sessionFactory;
    public static SessionFactory getSessionFactory() {
        if (sessionFactory == null) {
            try {
                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.CURRENT_SESSION_CONTEXT_CLASS, "thread");

                settings.put(Environment.HBM2DDL_AUTO, "create-drop");

                configuration.setProperties(settings);

                configuration.addAnnotatedClass(Student.class);

                ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
                    .applySettings(configuration.getProperties()).build();

                sessionFactory = configuration.buildSessionFactory(serviceRegistry);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return sessionFactory;
    }
}

Using @NamedQuery and @NamedQueries Annotations Example

Create an @Entity class and annotate it with the @NamedQuery and @NamedQueries annotation for using single or multiple named HQL/JPQL query expression as follows.
package net.javaguides.hibernate.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedNativeQueries;
import javax.persistence.NamedNativeQuery;
import javax.persistence.Table;

@Entity
@Table(name = "student")

@NamedNativeQuery(name = "GET_STUDENTS_COUNT", query = "select count(1) from student")

@NamedNativeQueries({
    @NamedNativeQuery(name = "GET_STUDENT_BY_ID", query = "select * from student where id=:id"),
    @NamedNativeQuery(name = "GET_ALL_STUDENTS", query = "select * from student", resultClass = Student.class)
})
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @Column(name = "email")
    private String email;

    public Student() {

    }

    public Student(String firstName, String lastName, String email) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "Student [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", email=" + email + "]";
    }

}

Run an Application - Use of a Named Query

Now, create a main class to execute the named query using the Session.createNamedQuery() method.
package net.javaguides.hibernate;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.Transaction;

import net.javaguides.hibernate.entity.Student;
import net.javaguides.hibernate.util.HibernateUtil;

public class NamedNativeQueryExample {
    @SuppressWarnings("unchecked")
    public static void main(String[] args) {

        saveStudent();

        Transaction transaction = null;
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            transaction = session.beginTransaction();
            // Executing named queries

            List < Object > totalStudents = session.createNamedQuery("GET_STUDENTS_COUNT").getResultList();
            System.out.println("Total Students: " + totalStudents.get(0));

            List < Object > student = session.createNamedQuery("GET_STUDENT_BY_ID").setParameter("id", 1).getResultList();

            System.out.println(student.get(0));

            List < Student > students = session.createNamedQuery("GET_ALL_STUDENTS", Student.class).getResultList();
            for (Student student1: students) {
                System.out.println("ID : " + student1.getId() + " \tNAME : " + student1.getFirstName());
            }

            transaction.commit();

        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        }

    }

    private static void saveStudent() {
        Transaction transaction = null;
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {

            // start a transaction
            transaction = session.beginTransaction();
            // create new student
            Student student = new Student("Ramesh", "Fadatare", "rameshfadatare@javaguides.com");
            // save the student object
            session.persist(student);
            // commit transaction
            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        }
    }
}

Using @NamedNativeQuery and @NamedNativeQueries Annotations Example

Create an @Entity class and annotate it with the @NamedNativeQuery and @NamedNativeQueries annotation for using single or multiple named native SQL query expression as follows.
package net.javaguides.hibernate.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedNativeQueries;
import javax.persistence.NamedNativeQuery;
import javax.persistence.Table;

@Entity
@Table(name = "student")

@NamedNativeQuery(name = "GET_STUDENTS_COUNT", query = "select count(1) from student")

@NamedNativeQueries({
    @NamedNativeQuery(name = "GET_STUDENT_BY_ID", query = "select * from student where id=:id"),
    @NamedNativeQuery(name = "GET_ALL_STUDENTS", query = "select * from student", resultClass = Student.class)
})
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @Column(name = "email")
    private String email;

    public Student() {

    }

    public Student(String firstName, String lastName, String email) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "Student [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", email=" + email + "]";
    }
}
The following example shows how to execute the named native queries, defined in the Student entity class, in hibernate.

NamedNativeQueryExample.java - Named Native Query

package net.javaguides.hibernate;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.Transaction;

import net.javaguides.hibernate.entity.Student;
import net.javaguides.hibernate.util.HibernateUtil;

public class NamedNativeQueryExample {
    @SuppressWarnings("unchecked")
    public static void main(String[] args) {

        saveStudent();

        Transaction transaction = null;
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            transaction = session.beginTransaction();
            // Executing named queries

            List < Object > totalStudents = session.createNamedQuery("GET_STUDENTS_COUNT").getResultList();
            System.out.println("Total Students: " + totalStudents.get(0));

            List < Object > student = session.createNamedQuery("GET_STUDENT_BY_ID").setParameter("id", 1).getResultList();

            System.out.println(student.get(0));

            List < Student > students = session.createNamedQuery("GET_ALL_STUDENTS", Student.class).getResultList();
            for (Student student1: students) {
                System.out.println("ID : " + student1.getId() + " \tNAME : " + student1.getFirstName());
            }

            transaction.commit();

        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        }

    }

    private static void saveStudent() {
        Transaction transaction = null;
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {

            // start a transaction
            transaction = session.beginTransaction();
            // create new student
            Student student = new Student("Ramesh", "Fadatare", "rameshfadatare@javaguides.com");
            // save the student object
            session.persist(student);
            // commit transaction
            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        }
    }
}

GitHub Repository

The complete source code of this article available on my GitHub Repository - https://github.com/RameshMF/Hibernate-ORM-Tutorials

Conclusion

In this article, we have discussed how to use Hibernate native queries in Hibernate applications.  In Hibernate, a named query is a JPQL or SQL expression with a predefined unchangeable query string. You can define a named query either in hibernate mapping file or in an entity class.
You can learn more about Hibernate ORM Framework at Hibernate Tutorial

References

Comments