在插入数据库之前检查资源是否存在,或者等到DAO抛出异常?

时间:2018-12-17 12:07:19

标签: java spring rest

我有两条路径:

  • /students
  • /students/{id}/addresses

...具有以下行为:

  • POST/students-201 Created(如果成功创建了学生)
  • POST/students/{id}/addresses-201 Created(如果在请求的用户下成功创建了地址)

现在,假设客户POST/students/12/addresses的情况,但没有id = 12的学生。

我应该如何处理这种情况?

我应该不加检查地插入并等待Hibernate抛出异常,还是应该在插入之前检查Student的存在性?

第一个选项:

StudentController.java

@Autowired
private AddressService addressService;

@PostMapping("/students/{id}/addresses")
public ResponseEntity<?> handleRequestOfCreateAddressToStudent(@PathVariable("id") Long studentId, @RequestBody Address address) {
    address.setStudent(new Student(studentId));
    Address createdAddress = addressService.saveAddress(address);

    URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").build(createdAddress.getId());
    return ResponseEntity.created(location).build();
}

AddressService.java

@Autowired
private AddressRepository addressRepository;

public Address saveAddress(Address address) {
    // omitted for brevity...
    return addressRepository.save(address);
}

这样,由于我使用的是Spring,因此应用程序将抛出DataIntegrityViolationException,因为违反了约束(不存在具有此类ID的Student与该地址绑定)。而且,由于我需要将响应发送给客户端,因此我必须转换抛出的异常。

第二个选项:

StudentController.java

@Autowired
private StudentService studentService;

@Autowired
private AddressService addressService;

@PostMapping("/students/{id}/addresses")
public ResponseEntity<?> handleRequestOfCreateAddressToStudent(@PathVariable("id") Long studentId, @RequestBody Address address) throws StudentNotFoundException {
    Student student = studentService.findById(studentId);

    if(student == null)
        throw new StudentNotFoundException("message");

    address.setStudent(new Student(studentId));
    Address createdAddress = addressService.saveAddress(address);

    URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").build(createdAddress.getId());
    return ResponseEntity.created(location).build();
}

这样,我不需要翻译异常,因为我已经知道Student不存在,因此我可以抛出自定义异常。

我在两种方法中的想法:

  1. 不进行检查,我确实减少了代码和触发数据库的次数;
  2. 进行检查,我确实知道为什么我无法添加地址(学生不存在)并且可以抛出自定义异常而不必翻译它的原因;

哪种方法是解决此问题的最佳方法?

我应该等待DAO抛出异常,还是应该通过检查Student是否存在来防止抛出异常?

1 个答案:

答案 0 :(得分:0)

您对您的2个结论是正确的,但我想再添加一件事供您考虑。第二种选择对您来说是一个不错的选择, 只有在遇到这种情况时您要执行一些特定的操作。如果您只是要像记录所有其他错误一样记录一条错误消息,那么将这种特殊情况与其他情况区分开来就是没有意义的。

这就是说:如果您的业务逻辑中没有针对此类事件的特殊处理,则转到选项1。否则-选项2。