JUnit Test Cases for Hibernate DAO

In this tutorial, we'll walk through how to write JUnit test cases for a Hibernate DAO (Data Access Object) using the latest version of Hibernate. We'll cover setting up a test environment, creating test cases, and running these tests to ensure our DAO methods work as expected.

Prerequisites

Before we start, ensure you have the following:

  • Java Development Kit (JDK) installed
  • Apache Maven installed
  • An IDE (Integrated Development Environment) like IntelliJ IDEA or Eclipse

Step 1: Setting Up the Project

Create a Maven Project

  1. Open your IDE and create a new Maven project.
  2. Define the project coordinates (groupId, artifactId, version) in the pom.xml file.

Project Structure

Your project structure should look like this:

hibernate-junit-example
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com
│   │   │       └── example
│   │   │           └── hibernate
│   │   │               ├── App.java
│   │   │               ├── model
│   │   │               │   └── Student.java
│   │   │               ├── util
│   │   │               │   └── HibernateUtil.java
│   │   │               └── dao
│   │   │                   └── StudentDao.java
│   │   └── resources
│   │       └── hibernate.cfg.xml
│   ├── test
│   │   └── java
│   │       └── com
│   │           └── example
│   │               └── hibernate
│   │                   └── dao
│   │                       └── StudentDaoTest.java
└── pom.xml

Step 2: Adding Dependencies

Add the necessary dependencies for Hibernate, H2 database, and JUnit in the pom.xml file.

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://www.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>hibernate-junit-example</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!-- Hibernate Core -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>6.1.6.Final</version>
        </dependency>

        <!-- H2 Database -->
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>2.1.214</version>
        </dependency>

        <!-- JUnit for testing -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.9.1</version>
            <scope>test</scope>
        </dependency>

        <!-- Hibernate Validator -->
        <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.2.3.Final</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Step 3: Configuring Hibernate

Create the Hibernate configuration file (hibernate.cfg.xml) in the src/main/resources directory.

hibernate.cfg.xml

<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- Database connection settings -->
        <property name="hibernate.connection.driver_class">org.h2.Driver</property>
        <property name="hibernate.connection.url">jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</property>
        <property name="hibernate.connection.username">sa</property>
        <property name="hibernate.connection.password"></property>

        <!-- SQL dialect -->
        <property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="hibernate.show_sql">true</property>

        <!-- Drop and re-create the database schema on startup -->
        <property name="hibernate.hbm2ddl.auto">create</property>

        <!-- Names the annotated entity class -->
        <mapping class="com.example.hibernate.model.Student"/>
    </session-factory>
</hibernate-configuration>

Step 4: Creating the Entity Class

Create an Entity class Student in the com.example.hibernate.model package.

Student.java

package com.example.hibernate.model;

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

@Entity
public class Student {

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

    private String name;
    private String email;

    // 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 getEmail() {
        return email;
    }

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

Step 5: Creating the Hibernate Utility Class

Create a utility class HibernateUtil to manage the Hibernate SessionFactory.

HibernateUtil.java

package com.example.hibernate.util;

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

public class HibernateUtil {

    private static SessionFactory sessionFactory;

    static {
        try {
            Configuration configuration = new Configuration();
            configuration.configure("hibernate.cfg.xml");
            ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
                    .applySettings(configuration.getProperties()).build();
            sessionFactory = configuration.buildSessionFactory(serviceRegistry);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

Step 6: Creating the DAO Class

Create a DAO (Data Access Object) class StudentDao to perform CRUD operations.

StudentDao.java

package com.example.hibernate.dao;

import com.example.hibernate.model.Student;
import com.example.hibernate.util.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.Transaction;

import java.util.List;

public class StudentDao {

    public void saveStudent(Student student) {
        Transaction transaction = null;
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            transaction = session.beginTransaction();
            session.save(student);
            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        }
    }

    public void updateStudent(Student student) {
        Transaction transaction = null;
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            transaction = session.beginTransaction();
            session.update(student);
            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        }
    }

    public Student getStudentById(Long id) {
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            return session.get(Student.class, id);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public List<Student> getAllStudents() {
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            return session.createQuery("from Student", Student.class).list();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public void deleteStudent(Long id) {
        Transaction transaction = null;
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            transaction = session.beginTransaction();
            Student student = session.get(Student.class, id);
            if (student != null) {
                session.delete(student);
            }
            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        }
    }
}

Step 7: Writing JUnit Test Cases

Create a test class StudentDaoTest in the src/test/java/com/example/hibernate/dao package to write JUnit test cases for the StudentDao methods.

StudentDaoTest.java

package com.example.hibernate.dao;

import com.example.hibernate.model.Student;
import com.example.hibernate.util.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.jupiter.api.*;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class StudentDaoTest {

    private StudentDao studentDao;

    @BeforeAll
    public void setUp() {
        studentDao = new StudentDao();
    }

    @AfterEach
    public void tearDown() {
        // Clean up after each test
        Transaction transaction = null;
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            transaction = session.beginTransaction();
            session.createQuery("DELETE FROM Student").executeUpdate();
            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        }
    }

    @Test
    public void testSaveStudent() {
        Student student = new Student();
        student.setName("John Doe");
        student.setEmail("john.doe@example.com");

        studentDao.saveStudent(student);

        Student retrievedStudent = studentDao.getStudentById(student.getId());
        assertNotNull(retrievedStudent);
        assertEquals(student.getName(), retrievedStudent.getName());
    }

    @Test
    public void testUpdateStudent() {
        Student student = new Student();
        student.setName("John Doe");
        student.setEmail("john.doe@example.com");

        studentDao.saveStudent(student);

        student.setName("Jane Doe");
        studentDao.updateStudent(student);

        Student retrievedStudent = studentDao.getStudentById(student.getId());
        assertNotNull(retrievedStudent);
        assertEquals("Jane Doe", retrievedStudent.getName());
    }

    @Test
    public void testGetStudentById() {
        Student student = new Student();
        student.setName("John Doe");
        student.setEmail("john.doe@example.com");

        studentDao.saveStudent(student);

        Student retrievedStudent = studentDao.getStudentById(student.getId());
        assertNotNull(retrievedStudent);
        assertEquals(student.getName(), retrievedStudent.getName());
    }

    @Test
    public void testGetAllStudents() {
        Student student1 = new Student();
        student1.setName("John Doe");
        student1.setEmail("john.doe@example.com");

        Student student2 = new Student();
        student2.setName("Jane Doe");
        student2.setEmail("jane.doe@example.com");

        studentDao.saveStudent(student1);
        studentDao.saveStudent(student2);

        List<Student> students = studentDao.getAllStudents();
        assertNotNull(students);
        assertEquals(2, students.size());
    }

    @Test
    public void testDeleteStudent() {
        Student student = new Student();
        student.setName("John Doe");
        student.setEmail("john.doe@example.com");

        studentDao.saveStudent(student);

        studentDao.deleteStudent(student.getId());

        Student retrievedStudent = studentDao.getStudentById(student.getId());
        assertNull(retrievedStudent);
    }
}

Step 8: Running the Tests

To run the tests, execute the test class StudentDaoTest in your IDE or using Maven. The tests will perform the following operations:

  1. Save a new student and verify that it was saved correctly.
  2. Update an existing student and verify that the changes were persisted.
  3. Retrieve a student by ID and verify that the correct student is returned.
  4. Retrieve all students and verify that the correct number of students is returned.
  5. Delete a student and verify that it was deleted correctly.

Conclusion

In this tutorial, we have walked through setting up a Hibernate project using Maven, creating an entity and DAO, and writing JUnit test cases to test the DAO methods. By following this tutorial, you should now have a good understanding of how to write JUnit test cases for Hibernate DAOs and ensure that your database operations are working correctly.

Comments