如何使用Hibernate和Spring Boot正确处理空结果集

时间:2016-06-10 20:57:17

标签: java spring hibernate spring-mvc

我有一个使用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

处理“无结果”查询的简单情况的正确方法是什么?

2 个答案:

答案 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);
}

<小时/> 有关以下内容的更详细讨论:

答案 1 :(得分:1)

如果没有返回结果,则没有spring crud存储库查找方法抛出异常。它们都返回空值。由于您在服务器端获得空指针异常,因此您必须尝试对返回的值执行操作,而不检查它是否为空。