According to the Quarkus docs, including the line below in the application.properties should result in delete statements to be batched.
quarkus.hibernate-orm.jdbc.statement-batch-size=1000
However, I can't get this to work. Regardless of this property all delete statements are sent to the database individually instead of in batches.
Is there anything else I need to do?
To reproduce, use a simple entity like this:
@Entity
@Table(name = "book")
public class Book {
@GeneratedValue(strategy = IDENTITY)
@Id
private Long id;
private String title;
public Book() {
}
public Long getId() {
return id;
}
}
insert records into the database like this (on PostgreSQL):
INSERT INTO book (id, title)
VALUES(generate_series(1, 200), 'a title');
and a simple integration test like this:
@QuarkusTest
class BookDeleteIT {
@Inject EntityManager em;
@Test
void deletes_records_in_batches() {
List<Book> books = getBooks();
deleteBooks(books);
}
@Transactional
List<Book> getBooks() {
return em.createQuery("SELECT b FROM Book b").getResultList();
}
@Transactional
void deleteBooks(List<Book> books) {
books.forEach(book -> delete(book));
}
private int delete(Book book) {
return em.createQuery("DELETE FROM Book b WHERE b.id = :id")
.setParameter("id", book.getId())
.executeUpdate();
}
}
When I run this test, the deletes are sent to the database individually instead of in batches.
I suppose the error is the way you're deleting a book: use
em.remove(book)
instead of the query and Hibernate will accumulate deletions.There are possibilities that deleting a managed entity using a query instead of
EntityManager
prevents your JPA provider (Hibernate) to manage entity lifecycle and do some optimizations (like batch deletion).