JPA EmptyResultDataAccessException处理

时间:2016-08-30 17:28:50

标签: java spring rest spring-data spring-data-jpa

我正在为大学项目编写一个简单的库API。我有一个带书籍的数据库,每个都有自己的ID。我正在使用Spring Boot来提供服务。我有BookRepository扩展JpaRepository<Book, Long>和服务实现。

@Service
public class BookServiceImpl implements BookService{

   @Autowired
   private BookRepository bookRepository;

   @Async
   @Override
   public void delete (Long id){
       bookRepository.delete(id);
    }
}

稍后,REST控制器处理请求:

@RestController
public class BookServiceController{

    @Autowired
    private BookService bookService;

    @RequestMapping(value="books/{id}", method = RequestMethod.DELETE)
    public ResponseEntity<Book> deleteBook (@PathVariable("id") Long id){
        bookService.delete(id);
        return new ResponseEntity<Book>(HttpStatus.OK);
    }
}

现在,如果我要删除一个不在数据库中的Book,例如ID为123,我会抛出一个EmptyResultDataAccessException。

我的问题是,我如何以及在何处处理异常,以及如何避免以这种方式抛出NullPointerException?

提前致谢。

2 个答案:

答案 0 :(得分:1)

DELETE操作的情况下,您实际上不再返回实体;你只是确认资源已经消失了。由于DELETE是幂等的(您可以多次删除记录),无论记录是否存在,您都可以返回相同的状态代码,如果找不到记录,则返回404。您还可以简化处理程序方法:

@DeleteMapping("/books/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT) // because you deleted it
public void deleteBook(@PathVariable Long id) {
    try {
        bookService.delete(id); // or just use the repository directly
    } catch (EmptyResultDataAccessException ex) {
        // either do nothing to return a 204, or
        throw new NotFoundException();
    }
}

您有一个表示状态的异常:

@ResponseStatus(HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException {}

EmptyResultDataAccessException 注释状态为NOT_FOUND,这似乎是合理的。这是一个潜在的增强请求。

答案 1 :(得分:1)

避免 EmptyResultDataAccessException 的最优雅方法是在您的 Repository 接口中定义特定方法以通过您的 id 字段进行删除。

假设您的 id 字段名为 bookId:

public interface BookRepository extends JpaRepository<Book, Long> {
    Long deleteByBookId(Long bookId);
}

这样就不会抛出异常了。

如果您的 id 字段被简单地称为 id,我还没有测试过该解决方案。