简体   繁体   English

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

[英]Check if resource exists before inserting to the database or wait until the DAO throw the Exception?

I have two paths: 我有两条路:

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

...with the following behavior: ...具有以下行为:

  • POST to /students - 201 Created (if successfully created the Student) POST/students - 201 Created (如果成功创建了Student)
  • POST to /students/{id}/addresses - 201 Created (if successfully created the Address under the requested user) POST/students/{id}/addresses - 201 Created (如果在请求的用户下成功创建了地址)

Now, imagine a situation where the client POST to /students/12/addresses , but there's no Student with id = 12. 现在,设想的情况下,客户端POST/students/12/addresses ,但有一个与ID = 12没有学生。

How should I handle this scenario? 我应该如何处理这种情况?

Should I insert without any check and wait for Hibernate to throw the Exceptions or, before inserting, I should check for Student's existance? 我应该插入而不进行任何检查并等待Hibernate抛出异常,还是应该在插入之前检查Student的存在性?

1st option: 一种选择:

StudentController.java 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 AddressService.java

@Autowired
private AddressRepository addressRepository;

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

This way, since I'm using Spring, the application would throw a DataIntegrityViolationException , because the constraint is violated (there's no Student with such ID to bind with that Address). 这样,由于我使用的是Spring,因此应用程序将抛出DataIntegrityViolationException ,因为违反了约束(不存在具有此类ID的Student与该Address绑定)。 And, since I need to send the response to the client, I would have to translate the exception that is throwed. 而且,由于我需要将响应发送给客户端,因此我必须转换抛出的异常。

2nd option: 第二个选择:

StudentController.java 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();
}

This way, I don't need to translate the Exception, as I already know that the Student does not exist so that I can throw a custom exception. 这样,我不需要翻译异常,因为我已经知道Student不存在,因此我可以抛出自定义异常。

My thoughts in both approaches: 我对两种方法的想法:

  1. Without checking, I do reduce the code and the number of times I trigger my database; 如果不检查,我确实减少了代码和触发数据库的次数;
  2. Checking, I do know exactly why I'm unable to add the Address (the Student does not exist) and can throw a custom exception without having to translate it; 通过检查,我确实知道为什么我无法添加地址(学生不存在)并且可以抛出自定义异常而无需翻译它的确切原因。

Which one is the best approach to this scenario? 哪种方法是解决此问题的最佳方法?

Should I wait for the DAO to throw the Exception, or should I prevent it from throwing by checking if the Student exists? 我应该等待DAO抛出异常,还是应该通过检查Student是否存在来防止抛出异常?

You are right about your 2 conclusions, but I'd like to add one more thing for you to consider. 您对2个结论的看法是正确的,但我想补充一件事供您考虑。 The second option will be a good choice for you only if you are about to do some specific actions upon encountering this specific situation. 仅当您要在遇到这种特定情况时执行某些特定操作时,第二个选项才是您的好选择。 If you are just going to log an error message as you do with all the other errors, then there's no point in telling apart this particular situation from others. 如果您只是要像记录所有其他错误一样记录一条错误消息,那么将这种特殊情况与其他情况区分开是没有意义的。

That being said: if there's no special processing for this kind of event in your business logic, then go for option 1. Otherwise - option 2. 话虽如此:如果您的业务逻辑中没有针对此类事件的特殊处理,请选择选项1。否则,选择选项2。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM