🎓 Top 15 Udemy Courses (80-90% Discount): My Udemy Courses - Ramesh Fadatare — All my Udemy courses are real-time and project oriented courses.
▶️ Subscribe to My YouTube Channel (178K+ subscribers): Java Guides on YouTube
▶️ For AI, ChatGPT, Web, Tech, and Generative AI, subscribe to another channel: Ramesh Fadatare on YouTube
Introduction
Batch processing in Hibernate allows you to group multiple operations into a single batch to reduce the number of database round-trips and improve performance. In this tutorial, we will:
- Set up a Maven project with Hibernate and MySQL dependencies.
- Configure Hibernate.
- Create an entity class (
Product). - Implement batch processing methods.
- Demonstrate batch processing with a sample application.
Step 1: Set Up Your Project
1.1 Create a Maven Project
Open your IDE and create a new Maven project.
1.2 Add Dependencies
Update your pom.xml file to include the necessary dependencies for Hibernate and MySQL.
<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.example</groupId> <artifactId>hibernate-batch-example</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <!-- Hibernate ORM --> <dependency> <groupId>org.hibernate.orm</groupId> <artifactId>hibernate-core</artifactId> <version>6.4.0.Final</version> </dependency> <!-- MySQL Connector --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.29</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.10.1</version> <configuration> <source>21</source> <target>21</target> </configuration> </plugin> </plugins> </build> </project> 1.3 Configure Hibernate
Create a file named hibernate.cfg.xml in the src/main/resources directory to configure Hibernate. This file contains the database connection settings and Hibernate properties.
<!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="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_db</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">password</property> <property name="hibernate.hbm2ddl.auto">update</property> <property name="hibernate.show_sql">true</property> <!-- Batch processing properties --> <property name="hibernate.jdbc.batch_size">20</property> <property name="hibernate.order_inserts">true</property> <property name="hibernate.order_updates">true</property> </session-factory> </hibernate-configuration> Replace hibernate_db, root, and password with your MySQL database name and credentials.
Explanation:
hibernate.dialectspecifies the SQL dialect to be used.hibernate.connection.driver_classspecifies the JDBC driver class.hibernate.connection.urlspecifies the JDBC URL for the database connection.hibernate.connection.usernameandhibernate.connection.passwordspecify the database credentials.hibernate.hbm2ddl.autospecifies the schema generation strategy.hibernate.show_sqlspecifies whether to show SQL statements in the logs.hibernate.jdbc.batch_sizespecifies the batch size for batch processing.hibernate.order_insertsandhibernate.order_updatesspecify whether to order inserts and updates to improve batching efficiency.
Step 2: Create the Entity Class
Create an entity class Product that will be mapped to a table in the database. This class uses annotations to define the entity and its fields.
package com.example.entity; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; @Entity public class Product { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String description; private double price; // 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 getDescription() { return description; } public void setDescription(String description) { this.description = description; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } } Explanation:
- The
@Entityannotation specifies that the class is an entity and is mapped to a database table. - The
@Idannotation specifies the primary key of the entity. - The
@GeneratedValue(strategy = GenerationType.IDENTITY)annotation specifies that the primary key is auto-incremented.
Step 3: Create the Hibernate Utility Class
Create a utility class HibernateUtil to manage the Hibernate SessionFactory. This class ensures a single instance of SessionFactory is created and provides a method to close it.
package com.example.util; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtil { private static final SessionFactory sessionFactory = buildSessionFactory(); private static SessionFactory buildSessionFactory() { try { // Create the SessionFactory from hibernate.cfg.xml return new Configuration().configure().buildSessionFactory(); } catch (Throwable ex) { // Make sure you log the exception, as it might be swallowed System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } public static void shutdown() { // Close caches and connection pools getSessionFactory().close(); } } Explanation:
- The
buildSessionFactorymethod creates theSessionFactoryfrom thehibernate.cfg.xmlconfiguration file. - The
getSessionFactorymethod returns the singleton instance ofSessionFactory. - The
shutdownmethod closes theSessionFactoryto release resources.
Step 4: Implement Batch Processing
Create a class ProductService to handle database operations with batch processing. This class includes methods for batch inserting and updating Product entities.
Batch Insert Products
package com.example.service; import com.example.entity.Product; import com.example.util.HibernateUtil; import org.hibernate.Session; import org.hibernate.Transaction; public class ProductService { public void batchInsertProducts(List<Product> products) { Session session = HibernateUtil.getSessionFactory().openSession(); Transaction transaction = null; try { transaction = session.beginTransaction(); for (int i = 0; i < products.size(); i++) { session.save(products.get(i)); if (i % 20 == 0) { // Flush a batch of inserts and release memory. session.flush(); session.clear(); } } transaction.commit(); } catch (Exception e) { if (transaction != null) { transaction.rollback(); } e.printStackTrace(); } finally { session.close(); } } // Methods for batch updating products can be added here. } Batch Update Products
package com.example.service; import com.example.entity.Product; import com.example.util.HibernateUtil; import org.hibernate.Session; import org.hibernate.Transaction; public class ProductService { // Batch insert method public void batchUpdateProducts(List<Product> products) { Session session = HibernateUtil.getSessionFactory().openSession(); Transaction transaction = null; try { transaction = session.beginTransaction(); for (int i = 0; i < products.size(); i++) { session.update(products.get(i)); if (i % 20 == 0) { // Flush a batch of updates and release memory. session.flush(); session.clear(); } } transaction.commit(); } catch (Exception e) { if (transaction != null) { transaction.rollback(); } e.printStackTrace(); } finally { session.close(); } } } Explanation:
- The
batchInsertProductsandbatchUpdateProductsmethods open a Hibernate session and begin a transaction. - A loop is used to save or update each product in the list. Every 20 operations (as specified by the batch size), the session is flushed and cleared to ensure the batch is processed and memory is released.
- The transaction is committed using
transaction.commit(), ensuring the changes are saved in the database.
If an exception occurs, the transaction is rolled back using transaction.rollback().
- The session is closed in the
finallyblock to release resources.
Step 5: Demonstrate Batch Processing
Create a MainApp class to demonstrate the batch processing functionality. This class calls the batch processing methods of ProductService.
package com.example.main; import com.example.entity.Product; import com.example.service.ProductService; import java.util.ArrayList; import java.util.List; public class MainApp { public static void main(String[] args) { ProductService productService = new ProductService(); // Create a list of products to insert List<Product> productsToInsert = new ArrayList<>(); for (int i = 1; i <= 100; i++) { Product product = new Product(); product.setName("Product " + i); product.setDescription("Description for product " + i); product.setPrice(100.0 + i); productsToInsert.add(product); } // Batch insert products System.out.println("Batch inserting products:"); productService.batchInsertProducts(productsToInsert); // Create a list of products to update List<Product> productsToUpdate = new ArrayList<>(); for (int i = 1; i <= 100; i++) { Product product = new Product(); product.setId((long) i); product.setName("Updated Product " + i); product.setDescription("Updated description for product " + i); product.setPrice(200.0 + i); productsToUpdate.add(product); } // Batch update products System.out.println("Batch updating products:"); productService.batchUpdateProducts(productsToUpdate); } } Explanation of the Code in Step 5
-
Create a
ProductServiceInstance:ProductService productService = new ProductService();An instance of
ProductServiceis created to call its methods for performing batch processing. -
Create a List of Products to Insert:
List<Product> productsToInsert = new ArrayList<>(); for (int i = 1; i <= 100; i++) { Product product = new Product(); product.setName("Product " + i); product.setDescription("Description for product " + i); product.setPrice(100.0 + i); productsToInsert.add(product); }A list of 100 products is created for batch insertion.
-
Batch Insert Products:
System.out.println("Batch inserting products:"); productService.batchInsertProducts(productsToInsert);The
batchInsertProductsmethod is called to insert the products in batches. -
Create a List of Products to Update:
List<Product> productsToUpdate = new ArrayList<>(); for (int i = 1; i <= 100; i++) { Product product = new Product(); product.setId((long) i); product.setName("Updated Product " + i); product.setDescription("Updated description for product " + i); product.setPrice(200.0 + i); productsToUpdate.add(product); }A list of 100 products is created for batch updating.
-
Batch Update Products:
System.out.println("Batch updating products:"); productService.batchUpdateProducts(productsToUpdate);The
batchUpdateProductsmethod is called to update the products in batches.
Sample Output
When you run the MainApp class, you should see the following output:
Batch inserting products: Batch updating products: This output indicates that the batch processing methods were called successfully. You can verify the batch insert and update operations by checking the database.
Conclusion
In this tutorial, we have successfully demonstrated how to implement batch processing in Hibernate using MySQL. We set up a Hibernate project, created an entity class, and implemented batch processing functionality for insert and update operations. This guide provides a solid foundation for optimizing database operations in your Hibernate-based applications.
Comments
Post a Comment
Leave Comment