evict() Method in Hibernate

Introduction

Here I am going to show you an example on evict() method in Hibernate. The method evict() removes a single object from Session cache in ORM (Object Relationship Mapping) framework Hibernate. So before you call evict() the object should be there in the Session cache. Therefore if you save the object first time, you have to save the object via Session.save(object). Subsequent update calls should follow through session.saveOrUpdate(object) or session.update(object) before calling evict() to remove the loaded object from the cache.

Whenever you pass an object to save(), update() or saveOrUpdate(), and whenever you retrieve an object using load(), get(), list(), iterate() or scroll(), that object is added to the internal cache of the Session.

When flush() is subsequently called, the state of that object will be synchronized with the database. If you do not want this synchronization to occur, or if you are processing a huge number of objects and need to manage memory efficiently, the evict() method can be used to remove the object and its collections from the first-level cache.

Here I will show you an example how an evict() method works in Hibernate.

Prerequisites

Hibernate 6.0.0.Alpha5 – 6.0.0.Alpha6, Java at least 8, MySQL 8.0.17 – 8.0.22, Gradle 6.5.1 – 6.7.1, Maven 3.6.3

Project Setup

You can create either Gradle or Maven based project in Eclipse or in your favorite IDE or tool. The name of the project is hibernate-evict-method-example.

If you are creating gradle based project then you can use below build.gradle script:

plugins {
    id 'java-library'
}

sourceCompatibility = 12
targetCompatibility = 12

repositories {
    jcenter()
}

dependencies {
    implementation 'org.hibernate.orm:hibernate-core:6.0.0.Alpha5' to 6.0.0.Alpha6
    implementation('mysql:mysql-connector-java:8.0.17/22')
    
    //required for jdk 9 or above
    runtimeOnly('javax.xml.bind:jaxb-api:2.4.0-b180830.0359')
}

If you are creating maven based project then you can use below maven 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://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.roytuts</groupId>
	<artifactId>hibernate-evict-method-example</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<maven.compiler.source>12</maven.compiler.source>
		<maven.compiler.target>12</maven.compiler.target>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.hibernate.orm</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>6.0.0.Alpha5 to 6.0.0.Alpha6</version>
		</dependency>
		
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>8.0.17 to 8.0.22</version>
		</dependency>
	</dependencies>

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

MySQL Table

Create a MySQL table. I will save or retrieve data from the below table through Hibernate API.

CREATE TABLE `employee` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `designation` varchar(50) NOT NULL,
  `joiningdate` varchar(20) NOT NULL,
  `phone` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

Hibernate Configuration

I am going to create Java based Hibernate configuration. This hibernate configuration is required to connect to your MySQL database.

I am also building SessionFactory from which later you can get non-thread safe Session object.

package com.roytuts.hibernate.evict.method.example;

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;

public class HibernateUtil {

	private static SessionFactory sessionFactory;

	public static SessionFactory getSessionFactory() {

		if (sessionFactory == null) {
			try {
				Properties settings = new Properties();

				settings.put(Environment.DRIVER, "com.mysql.cj.jdbc.Driver");
				settings.put(Environment.URL, "jdbc:mysql://localhost:3306/roytuts");
				settings.put(Environment.USER, "root");
				settings.put(Environment.PASS, "root");
				settings.put(Environment.DIALECT, "org.hibernate.dialect.MySQLDialect");
				settings.put(Environment.SHOW_SQL, "true");
				settings.put(Environment.FORMAT_SQL, "true");
				settings.put(Environment.CURRENT_SESSION_CONTEXT_CLASS, "thread");

				Configuration configuration = new Configuration();
				configuration.setProperties(settings);

				configuration.addAnnotatedClass(Employee.class);

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

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

		return sessionFactory;
	}

	public static void closeSession() {
		// Close caches and connection pools
		getSessionFactory().close();
	}

}

Domain Object

Create POJO class that will be used as a domain object to map database table columns to Java fields.

package com.roytuts.hibernate.evict.method.example;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table
public class Employee {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
	private String name;
	private String designation;
	private String joiningdate;
	private String phone;

	public Employee() {
	}

	public Employee(String name, String designation, String joiningdate, String phone) {
		this.name = name;
		this.designation = designation;
		this.joiningdate = joiningdate;
		this.phone = phone;
	}

	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 getDesignation() {
		return designation;
	}

	public void setDesignation(String designation) {
		this.designation = designation;
	}

	public String getJoiningdate() {
		return joiningdate;
	}

	public void setJoiningdate(String joiningdate) {
		this.joiningdate = joiningdate;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	@Override
	public String toString() {
		return "Employee ID: " + id + ", Name: " + name + ", Designation: " + designation + ", Joining Date: "
				+ joiningdate + ", Phone: " + phone;
	}
}

Main Class

Create a class with main method for testing the application code.

I am going to save a record to the database table. Later retrieve the same record from the Session using load() method. Then I will use evict() method to check whether the object still there or not in the Session.

package com.roytuts.hibernate.evict.method.example;

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

public class EvictMethodTest {

	public static void main(String[] args) {
		Session session = null;
		Transaction transaction = null;

		try {
			session = HibernateUtil.getSessionFactory().openSession();
			transaction = session.beginTransaction();

			Employee employee = new Employee();
			employee.setName("Soumitra");
			employee.setDesignation("Designation");
			employee.setJoiningdate("18-Dec-2018");
			employee.setPhone("1234567890");

			session.save(employee);

			System.out.println("Employee saved: " + employee);
			System.out.println();

			Employee employee1 = (Employee) session.load(Employee.class, 6l);

			System.out.println("Before evict() session contains employee1 : " + session.contains(employee1));

			session.evict(employee1);
			System.out.println("After evict() session contains employee1 : " + session.contains(employee1));

		} catch (Exception e) {
			transaction.rollback();
			e.printStackTrace();
		} finally {
			transaction.commit();
			if (session != null) {
				HibernateUtil.closeSession();
			}
		}

	}

}

Testing the Application

Now check how evict() method works in Hibernate by running the above main class. You will get below output in the console:

Hibernate: 
    insert 
    into
        Employee
        (designation, joiningdate, name, phone) 
    values
        (?, ?, ?, ?)
Employee saved: Employee ID: 6, Name: Soumitra, Designation: Designation, Joining Date: 18-Dec-2018, Phone: 1234567890

Before evict() session contains employee1 : true
After evict() session contains employee1 : false

The above output clearly shows that before calling evict() method the object persists in the first level cache, i.e., in Session object and when evict() method is called then the object from the first level session gets removed.

Source Code

Download

Leave a Reply

Your email address will not be published. Required fields are marked *