简体   繁体   中英

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 to /students/{id}/addresses - 201 Created (if successfully created the Address under the requested user)

Now, imagine a situation where the client POST to /students/12/addresses , but there's no Student with 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?

1st option:

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

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). 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

@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.

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?

You are right about your 2 conclusions, but I'd like to add one more thing for you to consider. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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