如何使用Hibernate和Spring Boot正确处理空结果集 [英] How to properly handle empty resultset with Hibernate and Spring Boot
问题描述
我有一个使用Hibernate和Spring Data JPA的CrudRepository
的Spring应用程序.如果查询的数据存在于数据库中,那么一切似乎都可以正常工作.但是,如果存在不返回任何结果的查询,则CrudRepository
返回null
,我得到一个NullPointerException
.因此,例如http://localhost:8080/api/id=3
,如果数据库中存在ID为3的行,则可以正常工作.如果没有ID为3的行,它将失败并显示:
I have a Spring app that is using Hibernate and the Spring Data JPA's CrudRepository
. Everything seems to work properly if the data that was queried for exists in the database. However, if there is a query that returns no result, the CrudRepository
returns null
and I get a NullPointerException
. So for example http://localhost:8080/api/id=3
if there is a row with id 3 in the database it works fine. If there isn't a row with id of 3 it fails with a:
发生意外错误(类型=内部服务器错误, 状态= 500)
there was an unexpected error (type=Internal Server Error, status=500)
在客户端,在服务器上是NullPointerException
.
On the client side and a NullPointerException
on the server side.
处理无结果"查询的简单情况的正确方法是什么?
What is the proper way of dealing with a simple case of a "No Results" query?
推荐答案
检查返回值,如果它不是null
,则以200 OK
响应的形式返回它的某种表示形式.否则,返回404 Not Found
.最后,您将拥有一个像这样的控制器:
Inspect the return value, if it's not null
, return some representation of it as a 200 OK
response. Otherwise, return a 404 Not Found
. In the end, you would have a controller like:
@RequestMapping(...)
public ResponseEntity<?> getOne(...) {
Something something = repository.findOne(...);
if (something == null)
return ResponseEntity.notFound().build();
return ResponseEntity.ok(something);
}
您可以重构前面的代码以合并Java 8的
Optional<T>
,如 JB Nizet . "https://stackoverflow.com/questions/37757048/how-to-properly-handle-empty-resultset-with-hibernate-and-spring-boot#comment62984085_37757236>评论.基本上,Optional<T>
只是可能包含或可能不包含类型T
的值的容器.您可以将此类型用作Spring Data JPA方法的返回类型,如下所示:
You can refactor the preceding code to incorporate Java 8's
Optional<T>
, as JB Nizet mentioned in the comments. Basically, Optional<T>
is just a container that may or may not hold a value of type T
. You can use this type as the return type of Spring Data JPA methods, something like the following:
public interface SomethingRepository extends CrudRepository<Something, Long> {
Optional<Something> findById(Long id);
}
然后为404 Not Found
定义一个例外:
@ResponseStatus(HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException {}
如果在控制器中引发类型为NotFoundException
的异常,Spring MVC的异常解析器将捕获该异常并将其转换为404 Not Found
HTTP响应.
If you throw an exception of type NotFoundException
in your controllers, Spring MVC's exception resolver would catch that exception and convert it to a 404 Not Found
HTTP response.
最后,您的控制器将是:
Finally your controller would be like:
@RequestMapping(...)
public Something getOne(...) {
return repository.findById(id).orElseThrow(NotFoundException::new);
}
有关以下内容的详细讨论:
For more detailed discussions on:
- Spring Data JPA's
Optional<T>
support, read here. - Spring MVC's exception resolvers, read here.
- Java 8's
Optional<T>
, read here. - REST best practices, you can check out the REST in Practice book.
这篇关于如何使用Hibernate和Spring Boot正确处理空结果集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!