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| Operation | Method | SQL |
|---|---|---|
| Create | persist(post) | insert |
| Read | find(Post.class, id) | select ... where id=?; returns null if there is no row |
| Update | change a field of a loaded object | update at commit |
| Delete | remove(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 formmerge 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 contextLoad the object again in the current transaction — em.remove(em.find(Post.class, post.getId())) — and then delete it.