Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Create, read, update, delete

CRUD stands for the four basic operations with data: create, read, update, delete. In Hibernate each of them is one call to EntityManager, and you write no SQL. In this lesson we go through all four on the Post entity.

All four operations

// src/main/java/com/example/blog/Main.java
package com.example.blog;
 
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;
 
public class Main {
    public static void main(String[] args) {
        try (EntityManagerFactory emf = Persistence.createEntityManagerFactory("blog")) {
            // Create
            Long id = emf.callInTransaction(em -> {
                Post post = new Post("Hello, Hibernate", "My first post");
                em.persist(post);
                return post.getId();
            });
            IO.println("Created post " + id);
 
            // Read
            Post post = emf.callInTransaction(em -> em.find(Post.class, id));
            IO.println("Read: " + post.getTitle());
 
            // Update
            emf.runInTransaction(em -> {
                Post managed = em.find(Post.class, id);
                managed.setTitle("CRUD with Hibernate");
            });
 
            // Delete
            emf.runInTransaction(em -> {
                Post managed = em.find(Post.class, id);
                em.remove(managed);
            });
 
            Post deleted = emf.callInTransaction(em -> em.find(Post.class, id));
            IO.println("After delete: " + deleted);
        }
    }
}

callInTransaction works like runInTransaction, but returns the lambda's result. Output:

Hibernate: insert into Post (body,title,id) values (?,?,?)
Created post 1
Hibernate: select p1_0.id,p1_0.body,p1_0.title from Post p1_0 where p1_0.id=?
Read: Hello, Hibernate
Hibernate: select p1_0.id,p1_0.body,p1_0.title from Post p1_0 where p1_0.id=?
Hibernate: update Post set body=?,title=? where id=?
Hibernate: select p1_0.id,p1_0.body,p1_0.title from Post p1_0 where p1_0.id=?
Hibernate: delete from Post where id=?
Hibernate: select p1_0.id,p1_0.body,p1_0.title from Post p1_0 where p1_0.id=?
After delete: null
OperationMethodSQL
Createpersist(post)insert
Readfind(Post.class, id)select ... where id=?; returns null if there is no row
Updatechange a field of a loaded objectupdate at commit
Deleteremove(post)delete

remove accepts only an object loaded in the same EntityManager, so it is preceded by find.

merge: changes from outside

In a real application an object often comes from outside the transaction: it was loaded in one request, edited in a form and sent back. To save such an object, use merge:

// src/main/java/com/example/blog/Main.java
Post post = emf.callInTransaction(em -> em.find(Post.class, 1L));
post.setTitle("Edited in a form");
 
Post merged = emf.callInTransaction(em -> em.merge(post));
IO.println("Merged: " + merged.getTitle());
Hibernate: select p1_0.id,p1_0.body,p1_0.title from Post p1_0 where p1_0.id=?
Hibernate: update Post set body=?,title=? where id=?
Merged: Edited in a form

merge loads the current row, copies all fields from the passed object into it and saves the result. It returns that loaded copy — keep working with the returned object, not with the one you passed in. The difference is explained in the next lesson.

Common mistake

Calling remove on an object that was loaded in a different, already closed EntityManager fails:

// src/main/java/com/example/blog/Main.java
emf.runInTransaction(em -> em.remove(post));
Exception in thread "main" java.lang.IllegalArgumentException: org.hibernate.DetachedObjectException: Given entity is not associated with the persistence context

Load the object again in the current transaction — em.remove(em.find(Post.class, post.getId())) — and then delete it.

Thanks for reading!

Donate to the site — we work hard for you.