我有一个使用Hibernate和Spring Data JPA CrudRepository
的Spring应用程序。如果查询的数据存在于数据库中,则一切似乎都能正常工作。但是,如果存在未返回结果的查询,则CrudRepository
会返回null
,我会得到NullPointerException
。所以例如http://localhost:8080/api/id=3
如果数据库中有一个id为3的行,它可以正常工作。如果没有id为3的行,则失败并显示:
出现意外错误(type = Internal Server Error, 状态= 500)
在客户端和服务器端的NullPointerException
。
处理“无结果”查询的简单情况的正确方法是什么?
答案 0 :(得分:13)
检查返回值,如果不是null
,则将其返回值作为200 OK
响应返回。否则,返回404 Not Found
。最后,您将拥有一个像:
@RequestMapping(...)
public ResponseEntity<?> getOne(...) {
Something something = repository.findOne(...);
if (something == null)
return ResponseEntity.notFound().build();
return ResponseEntity.ok(something);
}
<小时/> 您可以重构前面的代码,将{8} JB Nizet中提到的Java
Optional<T>
合并为comments。基本上,Optional<T>
只是一个容器,可能包含也可能不包含T
类型的值。您可以将此类型用作Spring Data JPA方法的返回类型,如下所示:
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响应。
最后你的控制器就像:
@RequestMapping(...)
public Something getOne(...) {
return repository.findById(id).orElseThrow(NotFoundException::new);
}
<小时/> 有关以下内容的更详细讨论:
Optional<T>
支持,read here。Optional<T>
,read here。答案 1 :(得分:1)
如果没有返回结果,则没有spring crud存储库查找方法抛出异常。它们都返回空值。由于您在服务器端获得空指针异常,因此您必须尝试对返回的值执行操作,而不检查它是否为空。