Hibernate – Delete a Record
Deleting a record in Hibernate requires loading the entity first (to make it a managed/persistent object) and then calling session.delete() or session.remove(). You can also delete without loading using an HQL DELETE statement for batch operations. This tutorial covers all approaches with a complete working example.
Prerequisites
- Java 8 or later
- Hibernate 5.x
- MySQL database
- Maven project
Database Table
CREATE TABLE product (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(45) DEFAULT NULL,
price DECIMAL(10,0) DEFAULT NULL,
quantity INT DEFAULT NULL,
description VARCHAR(450) DEFAULT NULL,
active TINYINT(1) DEFAULT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!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="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/java9rdb</property>
<property name="connection.username">root</property>
<property name="connection.password">yourpassword</property>
<property name="dialect">org.hibernate.dialect.MySQL8Dialect</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<mapping class="com.java9r.model.Product"/>
</session-factory>
</hibernate-configuration>
Product Entity
package com.java9r.model;
import javax.persistence.*;
@Entity
@Table(name = "product")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "name", length = 45)
private String name;
@Column(name = "price")
private Long price;
@Column(name = "quantity")
private Integer quantity;
@Column(name = "description", length = 450)
private String description;
@Column(name = "active")
private Boolean active;
public Product() {}
public Integer getId() { return id; }
public String getName() { return name; }
public Long getPrice() { return price; }
public Integer getQuantity() { return quantity; }
public Boolean getActive() { return active; }
@Override
public String toString() {
return String.format("Product{id=%d, name='%s', price=%d}", id, name, price);
}
}
HibernateUtil
package com.java9r.util;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static final SessionFactory sessionFactory =
new Configuration().configure().buildSessionFactory();
public static SessionFactory getSessionFactory() { return sessionFactory; }
public static void shutdown() { sessionFactory.close(); }
}
ProductDAO – Delete Approaches
package com.java9r.dao;
import com.java9r.model.Product;
import com.java9r.util.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.Transaction;
public class ProductDAO {
// ------------------------------------------------------------------
// Approach 1: Load first, then delete — most common pattern
// session.remove() is the JPA-standard equivalent of session.delete()
// ------------------------------------------------------------------
public void deleteById(Integer id) {
Transaction tx = null;
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
tx = session.beginTransaction();
Product product = session.get(Product.class, id);
if (product == null) {
System.out.println("Product not found with id: " + id);
return;
}
session.delete(product); // or session.remove(product) in JPA
tx.commit();
System.out.println("Successfully deleted: " + product);
} catch (Exception e) {
if (tx != null) tx.rollback();
throw e;
}
}
// ------------------------------------------------------------------
// Approach 2: HQL DELETE — removes without loading the entity first
// Use this for batch deletes or when performance matters
// ------------------------------------------------------------------
public int deleteByHQL(Integer id) {
Transaction tx = null;
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
tx = session.beginTransaction();
int rows = session.createQuery("DELETE FROM Product WHERE id = :id")
.setParameter("id", id)
.executeUpdate();
tx.commit();
System.out.println("Rows deleted: " + rows);
return rows;
} catch (Exception e) {
if (tx != null) tx.rollback();
throw e;
}
}
// ------------------------------------------------------------------
// Approach 3: Delete all inactive products (bulk HQL delete)
// ------------------------------------------------------------------
public int deleteAllInactive() {
Transaction tx = null;
try (Session session = HibernateUtil.getSessionFactory().openSession()) {
tx = session.beginTransaction();
int rows = session.createQuery("DELETE FROM Product WHERE active = false")
.executeUpdate();
tx.commit();
System.out.println("Inactive products deleted: " + rows);
return rows;
} catch (Exception e) {
if (tx != null) tx.rollback();
throw e;
}
}
}
Main Class
package com.java9r;
import com.java9r.dao.ProductDAO;
import com.java9r.util.HibernateUtil;
public class DeleteProductMain {
public static void main(String[] args) {
ProductDAO dao = new ProductDAO();
// Delete product with id = 5 (load first, then delete)
dao.deleteById(5);
// Delete product with id = 6 using HQL (no SELECT query issued)
dao.deleteByHQL(6);
// Bulk delete all inactive products
dao.deleteAllInactive();
HibernateUtil.shutdown();
}
}
Expected Output
Hibernate: select ... from product where id=?
Hibernate: delete from product where id=?
Successfully deleted: Product{id=5, name='Keyboard', price=2500}
Hibernate: delete from product where id=?
Rows deleted: 1
Hibernate: delete from product where active=?
Inactive products deleted: 2
delete() vs HQL DELETE – Comparison
| Approach | SQL Queries Issued | Cascades Honored? | Best For |
|---|---|---|---|
session.delete(entity) |
SELECT + DELETE | Yes | Single record, cascaded deletes |
| HQL DELETE | DELETE only | No | Batch deletes, performance-critical paths |
Important Notes
- You can only delete a persistent (managed) entity. If you pass a detached object, use
session.merge()to re-attach it first. - HQL DELETE bypasses Hibernate's first-level cache and does not trigger cascade operations defined on associations.
- Always handle the case where
session.get()returnsnull— the record may not exist. - Wrap every delete in a transaction and roll back on exception to keep the database consistent.
Summary
Hibernate offers two main ways to delete a record: load the entity with session.get() and call session.delete(), or use an HQL DELETE statement. The first approach is appropriate when you need cascade behavior (deleting associated child records). Use HQL DELETE for bulk removals where loading each entity would be too slow. Always wrap delete operations in a transaction.
Comments