Springboot服务类-异常处理

发布于 2025-01-19 04:58:27 字数 1056 浏览 0 评论 0原文

我有一个新创建的Springboot服务类,可以使用JPA派生的分类来处理CRUD操作。

在Internet上有很多示例,有些包括已有检查删除,更新(和GET)的检查 - 有些没有。

这就是我的样子:

public class BirdServiceImpl implements BirdService {

    private final BirdRepository birdRepository;

    @Override
    public Bird create(Bird bird) {
        log.info("Saving new bird: {}", bird.getName() );
        return birdRepository.save(bird);
    }

    @Override
    public Collection<Bird> list() {
        log.info("Finding all birds");
        return birdRepository.findAll();
    }

    @Override
    public Bird get(Long id) {
        return birdRepository.findById(id).get();
    }

    @Override
    public Bird update(Bird bird) {
        return null;
    }

    @Override
    public void delete(Long id) {
        log.info("About to delete bird : {}", id);
        Bird bird = new Bird();
        if (birdRepository.existsById(id)) {
             birdRepository.deleteById(id);
        }
    }
}

问题:这些检查是否应该存在在那里,还是应该有一些例外处理,如果是在哪里?

如何确定删除成功,因为它没有返回任何内容?

I have a newly created Springboot service class to handle CRUD operations using the JPA derived classed.

There are many examples of this on the internet, some include existsById checks on delete, update (and get) - some don't.

This is what mine looks like:

public class BirdServiceImpl implements BirdService {

    private final BirdRepository birdRepository;

    @Override
    public Bird create(Bird bird) {
        log.info("Saving new bird: {}", bird.getName() );
        return birdRepository.save(bird);
    }

    @Override
    public Collection<Bird> list() {
        log.info("Finding all birds");
        return birdRepository.findAll();
    }

    @Override
    public Bird get(Long id) {
        return birdRepository.findById(id).get();
    }

    @Override
    public Bird update(Bird bird) {
        return null;
    }

    @Override
    public void delete(Long id) {
        log.info("About to delete bird : {}", id);
        Bird bird = new Bird();
        if (birdRepository.existsById(id)) {
             birdRepository.deleteById(id);
        }
    }
}

QUESTION: Should those checks existsById be in there or should there be some Exception Handling and if so where?

How can one be sure that the delete was successful as it doesn't return anything?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

窝囊感情。 2025-01-26 04:58:28

据我所知,deleteById在以下情况

  1. 下,如果给定ID为null illegalArgumentException,则会抛出两个例外。
  2. 如果给定ID在持久存储中不存在eyaterResultDataAccessexception

无需使用已有检查,因为它将启动不必要的查询到持久性商店(数据库)。

我的建议将遵循:

  1. 如果没有什么特别的话,除了仅在API响应中返回特定的http status,请不要在<<<<代码>服务层。这里可能有两种情况

    1.1您想为每个服务处理所有现有的ID案例。在这种情况下,您想在控制器建议中处理此操作。返回预定义的HTTP状态和适当的错误消息,用于服务层抛出的异常。

    1.2您可能要处理删除因非存在而失败,在这种情况下,请声明runtime exception延长的专用异常类。在服务中捕获emptyResultDataAccessexception,并准备新创建的异常的异常对象,然后将其投掷。然后在控制器建议中处理该异常特别是。

以下是如何处理控制器建议中的异常,

@RestControllerAdvice()
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
    @ExceptionHandler(EmptyResultDataAccessException.class)
    @ResponseStatus(value = HttpStatus.NOT_FOUND)
    public ResponseEntity error(EmptyResultDataAccessException ex) {
        return ...; // Build your response body here.
    }
}
  1. 您可能想执行一些特殊的事情,例如我的删除呼叫失败的方式。在这种情况下,请捕获Service内的异常,然后执行您想做的事情(即,您可以在该ID删除失败的活动日志中记录输入)。完成业务任务后,提出适当的异常(基于1.11.2,无论哪种适合您的案例),该均应在Controller建议。

As per my knowledge two exception is thrown by the deleteById in following cases

  1. In case the given id is null IllegalArgumentException is thrown.
  2. In case given id is not present in the persistence store EmptyResultDataAccessException is thrown.

There is no need to check using existsById as it will initiate unnecessary query to the persistence store (Database).

My suggestion would be following:

  1. If nothing special to be done, except just returning particular HTTP Status in the api response, then do not handle this exception in the Service layer. Two cases are possible here

    1.1 You want to handle every non existing id cases similarly for every services. In that case you want to handle this in the Controller Advice. Return predefined http status and proper error message for the exceptions thrown by the Service layers.

    1.2 You might want to handle deletion failed due to non existence differently, in that case declare a dedicate exception class extended from RuntimeException. Catch the EmptyResultDataAccessException inside the service and prepare a exception object of your newly created exception then throw it. Then handle that exception inside the Controller Advice specially.

Following is how to handle exception in Controller Advice

@RestControllerAdvice()
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
    @ExceptionHandler(EmptyResultDataAccessException.class)
    @ResponseStatus(value = HttpStatus.NOT_FOUND)
    public ResponseEntity error(EmptyResultDataAccessException ex) {
        return ...; // Build your response body here.
    }
}
  1. You might want to do some special things like how my deletion call failed. In that case catch the exception inside the Service and do what you want to do (i.e you may log entry in the activity log that deletion failed for that id). After doing your business task throw appropriate exception (based on point 1.1 or 1.2 whichever suits your case well) which is meant to be handled in the Controller Advice.
爺獨霸怡葒院 2025-01-26 04:58:28

您可以使用已有的ByistbyId,如果它返回true,则可以删除特定的记录,否则您可以抛出它不存在的例外。

           if (birdRepository.existsById(id)) {
                     birdRepository.deleteById(id);
                }else {
                     throw new EmptyResultDataAccessException(
                     String.format("No %s entity with id %s exists!", entityInformation.getJavaType(), id), 1)
    );
  }

You can use existsById and if it returns true you can delete the specific record otherwise you can throw an exception that it didn't exist.

           if (birdRepository.existsById(id)) {
                     birdRepository.deleteById(id);
                }else {
                     throw new EmptyResultDataAccessException(
                     String.format("No %s entity with id %s exists!", entityInformation.getJavaType(), id), 1)
    );
  }
☆獨立☆ 2025-01-26 04:58:28

另一个选项可以使用可选容器。

    Bird bird = birdRepository.findById(id)
                  .orElseThrow(() -> new  EmptyResultDataAccessException(
                         String.format("No %s entity with id %s exists!", entityInformation.getJavaType(), id), 1)))

   birdRepository.delete(bird);
  • 取决于您是否要处理运行时间异常并序列化自定义响应并将其发送回客户端。如果是,您可以使用上述方法并在控制器建议中处理此方法。

  • 另一个选项是,您可以直接处理控制器建议中的异常,而无需明确地从服务层抛出任何内容。像操作 inlegalargument 例外或 keneryResultDataAccessexception 在控制器建议中。

Another option can be using Optional Container.

    Bird bird = birdRepository.findById(id)
                  .orElseThrow(() -> new  EmptyResultDataAccessException(
                         String.format("No %s entity with id %s exists!", entityInformation.getJavaType(), id), 1)))

   birdRepository.delete(bird);
  • It depends whether you want to handle Run Time exceptions and serialize custom response and send back to client. If yes, you can use above approach and handle this in Controller Advice.

  • Another option would be, you can directly handle the exception in Controller Advice without explicitly throwing anything from service layer. Like handling IllegalArgument Exception or EmptyResultDataAccessException in Controller Advice.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文