Expand Authors Top

If you have a few years of experience in the Java ecosystem and you’d like to share that with the community, have a look at our Contribution Guidelines.

Expanded Audience – Frontegg – Security (partner)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

NPI – JPA Buddy – JPA (partner)
announcement - icon

JPA is huge! It covers nearly every aspect of communication between relational databases and the Java application and is deeply integrated into all major frameworks.

If you're using IntelliJ, JPA Buddy is super helpful. The plugin gently guides you through the subtleties of the most popular JPA implementations, visually reminds you of JPA features, generates code that follows best practices, and integrates intelligent inspections to improve your existing persistence code.

More concretely, it provides powerful tooling to generate Spring Data JPA repositories and methods, Flyway Versioned Migrations, Liquibase Differential Changelogs, DDL and SQL statements, DTO objects, and MapStruct interfaces.

Oh, and it actually generates JPA entities from an existing database and gradually update the data model as the database evolves! Yeah.

>> Become a lot more productive with JPA Buddy

1. Overview

In this tutorial, we'll have a look at how deleting is done in Spring Data JPA.

2. Sample Entity

As we know from the Spring Data JPA reference documentation, repository interfaces provide us some basic support for entities.

Let's say we have an entity, such as a Book:

public class Book {

    private Long id;
    private String title;

    // standard constructors

    // standard getters and setters

Then we can extend Spring Data JPA's CrudRepository to give us access to CRUD operations on Book:

public interface BookRepository extends CrudRepository<Book, Long> {}

3. Delete from Repository

Among others, CrudRepository contains two methods: deleteById and deleteAll.

Let's test these methods directly from our BookRepository:

@SpringBootTest(classes = {Application.class})
public class DeleteFromRepositoryUnitTest {

    private BookRepository repository;

    Book book1;
    Book book2;
    List<Book> books;

    // data initialization

    public void whenDeleteByIdFromRepository_thenDeletingShouldBeSuccessful() {

    public void whenDeleteAllFromRepository_thenRepositoryShouldBeEmpty() {

And even though we are using CrudRepository, note that these same methods exist for other Spring Data JPA interfaces such as JpaRepository or PagingAndSortingRepository.

4. Derived Delete Query

We can also derive query methods for deleting entities. There is a set of rules for writing them, but let's just focus on the simplest example.

A derived delete query must start with deleteBy, followed by the name of the selection criteria. These criteria must be provided in the method call.

Let's say that we want to delete Books by title. Using the naming convention, we'd start with deleteBy and list title as our criteria:

public interface BookRepository extends CrudRepository<Book, Long> {
    long deleteByTitle(String title);

The return value, of type long, indicates how many records the method deleted.

Let's write a test and make sure that is correct:

public void whenDeleteFromDerivedQuery_thenDeletingShouldBeSuccessful() {
    long deletedRecords = repository.deleteByTitle("The Hobbit");

Persisting and deleting objects in JPA requires a transaction. That's why we should use a @Transactional annotation when using these derived delete queries, to make sure a transaction is running. This is explained in detail in the ORM with Spring documentation.

5. Custom Delete Query

The method names for derived queries can get quite long, and they are limited to just a single table.

When we need something more complex, we can write a custom query using @Query and @Modifying together.

Let's check the equivalent code for our derived method from earlier:

@Query("delete from Book b where b.title=:title")
void deleteBooks(@Param("title") String title);

Again, we can verify it works with a simple test:

public void whenDeleteFromCustomQuery_thenDeletingShouldBeSuccessful() {
    repository.deleteBooks("The Hobbit");

Both solutions presented above are similar and achieve the same result. However, they take a slightly different approach.

The @Query method creates a single JPQL query against the database. By comparison, the deleteBy methods execute a read query and then delete each of the items one by one.

6. Delete in Relationships

Now let's see what happens when we have relationships with other entities.

Assume we have a Category entity that has a OneToMany association with the Book entity:

public class Category {

    private Long id;
    private String name;

    @OneToMany(mappedBy = "category", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Book> books;

    // standard constructors

    // standard getters and setters

The CategoryRepository can just be an empty interface that extends CrudRepository:

public interface CategoryRepository extends CrudRepository<Category, Long> {}

We should also modify the Book entity to reflect this association:

private Category category;

Let's now add two categories and associate them with the books we currently have.

Now if we try to delete the categories, the books will also be deleted:

public void whenDeletingCategories_thenBooksShouldAlsoBeDeleted() {

This is not bi-directional, though, meaning that if we delete the books, the categories are still there:

public void whenDeletingBooks_thenCategoriesShouldAlsoBeDeleted() {

We can change this behavior by changing the properties of the relationship, such as the CascadeType.

7. Conclusion

In this article, we saw different ways to delete entities in Spring Data JPA.

We looked at the provided delete methods from CrudRepository as well as our derived queries or custom ones using @Query annotation.

We also saw how deleting is done in relationships.

As always, all of the code snippets mentioned in this article can be found on our GitHub repository.

Persistence bottom

Get started with Spring Data JPA through the reference Learn Spring Data JPA course:

Persistence footer banner
Comments are closed on this article!