Hibernate HQL with Spring Boot Tutorial

Hibernate Query Language (HQL) is a powerful query language provided by Hibernate, which is used to perform various database operations. HQL is similar to SQL but operates on Hibernate's entity objects. This tutorial will guide you through the usage of HQL in a Spring Boot application with the latest versions of Spring Boot and Hibernate.

Prerequisites

Before we start, ensure you have the following:

  • Java Development Kit (JDK) installed
  • A Spring Boot project set up (you can create one using Spring Initializr)
  • Basic knowledge of Spring Boot, JPA, and Hibernate

Step 1: Setting Up the Project

Create a Spring Boot project using Spring Initializr with the following dependencies:

  • Spring Web
  • Spring Data JPA
  • H2 Database (for simplicity, but you can use any database of your choice)

Project Structure

Your project structure should look like this:

src/main/java
└── com
    └── example
        └── hql
            ├── HqlDemoApplication.java
            ├── model
            │   └── Employee.java
            ├── repository
            │   └── EmployeeRepository.java
            ├── service
            │   └── EmployeeService.java
            └── controller
                └── EmployeeController.java

Step 2: Creating the Entity Class

Create an Employee entity class with necessary fields.

Employee Entity

package com.example.hql.model;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;

@Entity
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private String department;
    private double salary;

    // Getters and Setters
    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDepartment() {
        return department;
    }

    public void setDepartment(String department) {
        this.department = department;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
}

Step 3: Creating the Repository Interface

Create a repository interface for the Employee entity.

EmployeeRepository

package com.example.hql.repository;

import com.example.hql.model.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
}

Step 4: Creating the Service Class

Create a service class to handle the business logic for the Employee entity. This service will contain methods using HQL.

EmployeeService

package com.example.hql.service;

import com.example.hql.model.Employee;
import com.example.hql.repository.EmployeeRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import java.util.List;

@Service
public class EmployeeService {

    @Autowired
    private EmployeeRepository employeeRepository;

    @PersistenceContext
    private EntityManager entityManager;

    public List<Employee> getAllEmployees() {
        return employeeRepository.findAll();
    }

    public Employee getEmployeeById(Long id) {
        return employeeRepository.findById(id).orElse(null);
    }

    public Employee saveEmployee(Employee employee) {
        return employeeRepository.save(employee);
    }

    public void deleteEmployee(Long id) {
        employeeRepository.deleteById(id);
    }

    // HQL Examples

    public List<Employee> getEmployeesByDepartment(String department) {
        String hql = "FROM Employee e WHERE e.department = :department";
        TypedQuery<Employee> query = entityManager.createQuery(hql, Employee.class);
        query.setParameter("department", department);
        return query.getResultList();
    }

    public List<Employee> getEmployeesWithSalaryGreaterThan(double salary) {
        String hql = "FROM Employee e WHERE e.salary > :salary";
        TypedQuery<Employee> query = entityManager.createQuery(hql, Employee.class);
        query.setParameter("salary", salary);
        return query.getResultList();
    }

    public List<Object[]> getEmployeeNamesAndDepartments() {
        String hql = "SELECT e.name, e.department FROM Employee e";
        TypedQuery<Object[]> query = entityManager.createQuery(hql, Object[].class);
        return query.getResultList();
    }

    public Long countEmployeesInDepartment(String department) {
        String hql = "SELECT COUNT(e) FROM Employee e WHERE e.department = :department";
        TypedQuery<Long> query = entityManager.createQuery(hql, Long.class);
        query.setParameter("department", department);
        return query.getSingleResult();
    }
}

Step 5: Creating the Controller Class

Create a controller class to expose RESTful endpoints for managing Employee entities and demonstrate HQL queries.

EmployeeController

package com.example.hql.controller;

import com.example.hql.model.Employee;
import com.example.hql.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/employees")
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;

    @GetMapping
    public List<Employee> getAllEmployees() {
        return employeeService.getAllEmployees();
    }

    @GetMapping("/{id}")
    public Employee getEmployeeById(@PathVariable Long id) {
        return employeeService.getEmployeeById(id);
    }

    @PostMapping
    public Employee createEmployee(@RequestBody Employee employee) {
        return employeeService.saveEmployee(employee);
    }

    @DeleteMapping("/{id}")
    public void deleteEmployee(@PathVariable Long id) {
        employeeService.deleteEmployee(id);
    }

    // HQL Endpoints

    @GetMapping("/department/{department}")
    public List<Employee> getEmployeesByDepartment(@PathVariable String department) {
        return employeeService.getEmployeesByDepartment(department);
    }

    @GetMapping("/salary/{salary}")
    public List<Employee> getEmployeesWithSalaryGreaterThan(@PathVariable double salary) {
        return employeeService.getEmployeesWithSalaryGreaterThan(salary);
    }

    @GetMapping("/names-and-departments")
    public List<Object[]> getEmployeeNamesAndDepartments() {
        return employeeService.getEmployeeNamesAndDepartments();
    }

    @GetMapping("/count/{department}")
    public Long countEmployeesInDepartment(@PathVariable String department) {
        return employeeService.countEmployeesInDepartment(department);
    }
}

Step 6: Creating the Application Class

Create the main application class to run your Spring Boot application.

HqlDemoApplication

package com.example.hql;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class HqlDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(HqlDemoApplication.class, args);
    }
}

Step 7: Testing the Application

Now that everything is set up, you can run your Spring Boot application and test the HQL queries. Use tools like Postman or cURL to interact with the RESTful API endpoints.

Example Requests

  1. Create a new employee:

    POST /employees
    Content-Type: application/json
    
    {
        "name": "John Doe",
        "department": "HR",
        "salary": 50000
    }
    
  2. Get all employees:

    GET /employees
    
  3. Get an employee by ID:

    GET /employees/{id}
    
  4. Delete an employee by ID:

    DELETE /employees/{id}
    

HQL Query Endpoints

  1. Get employees by department:

    GET /employees/department/{department}
    
  2. Get employees with salary greater than a specific amount:

    GET /employees/salary/{salary}
    
  3. Get employee names and departments:

    GET /employees/names-and-departments
    
  4. Count employees in a department:

    GET /employees/count/{department}
    

Verifying HQL Queries

  • Get employees by department: Verify that the query returns employees belonging to the specified department.
  • Get employees with salary greater than a specific amount: Verify that the query returns employees whose salaries are greater than the specified amount.
  • Get employee names and departments: Verify that the query returns a list of employee names and their respective departments.
  • Count employees in a department: Verify that the query returns the correct count of employees in the specified department.

Conclusion

In this tutorial, we have explored how to use Hibernate Query Language (HQL) in a Spring Boot application. We created an Employee entity, implemented a repository, created a service class with various HQL queries, and exposed these queries through a RESTful controller. Understanding and using HQL is crucial for performing complex queries on your entity objects in a Hibernate-based application.


Comments