Home > Back-end >  Spring JPA Derived Delete with Optional Return Type returns the deleted entity count instead of the
Spring JPA Derived Delete with Optional Return Type returns the deleted entity count instead of the

Time:10-12

I have a Spring Boot application to track books. The Book entity is similar to this.

@Entity
@DynamicUpdate
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Builder
public class Book implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long bookId;
    
    @Column(nullable = false, unique = true)
    private String bookName;
}

And it has a repository, via which I can delete a book by its bookName attribute.

@Repository
public interface BookRepository extends JpaRepository<Book, String> {
    Optional<Book> deleteByBookName(String bookName);
}

And my delete method looks like this.

@Transactional
public void deleteBook(String bookName) {

  Optional<Book> deletedBook = bookRepository.deleteByBookName(bookName);
  if (deletedBook.isEmpty()) {
      throw new ResourceNotFoundException("Book Not Found");
  }

}

However, instead of returning an Optional<Book> type instance, this deleteByBookName method returns Optional objects such as Optional[0], Optional[1] which have the deleted book counts as values.

Due to this, deletedBook.isEmpty() is always true, even when 0 books are deleted.

Why this deleteByBookName method returns the deleted count inside Optional, instead of the deleted entity?

CodePudding user response:

The solution would be to check the deleted count instead of deleted object.

You should refactor the method to check deleted count as shown below.

@Transactional
public void deleteBook(String bookName) {

  Integer deletedBookCount = bookRepository.deleteByBookName(bookName);
  if (deletedBookCount == null || deletedBookCount == 0) {
      throw new ResourceNotFoundException("Book Not Found");
  }

}

Accordingly, change Repository method's signature.

@Repository
public interface BookRepository extends JpaRepository<Book, String> {
    Integer deleteByBookName(String bookName);
}

CodePudding user response:

Spring Data doesn't return deleted object after delete operation, it can returns only the deleted objects count or void. You can have a look also in the Spring official documentation.

delete…By, remove…By - Delete query method returning either no result (void) or the delete count.
  • Related