提问人:tabool 提问时间:9/25/2023 最后编辑:Jenstabool 更新时间:9/25/2023 访问量:54
@Transactional避免存储库方法中的异常
@Transactional avoids exception in repository methods
问:
我正在使用服务方法@Transactional
假设我们有这样的方法
@Transactional
public void doWork() {
User user = new User(1);
user = userRepository.save(user);
doOtherWorkIfAllIsOk(user);
}
private void doOtherWorkIfAllIsOk(User user) {
System.out.println("Everything is alright");
user.setName("Bob")
userRepository.save(user);
}
例如,如果我没有为用户填写一些必填字段,该字段具有 ,则事务将捕获一个异常,该异常将抛出存储库方法,并且我的方法将通过调用该方法继续执行。nullable = false
doOtherWorkIfAllIsOk()
如何配置事务行为,以便 Spring 在调用存储库方法时不会捕获异常。我需要的是,如果存储库方法中发生错误,则 doWork() 方法会抛出此异常并被中断,并且不应调用 doOtherWorkIfAllIsOk(User user) 方法,因为现在如果存储库方法中出现错误,则调用 doOtherWorkIfAllIsOk(User user) 方法。
答:
0赞
Hermann Steidel
9/25/2023
#1
我会考虑一种不同的方法。可以改进让数据库或持久性框架自动引发错误,然后捕获这些错误以控制代码流。有很多方法可以做到这一点,但我会考虑如下:
@Transactional
public void doWork() {
User user = new User(1);
if (isUserValid(user)) {
user = userRepository.save(user);
doOtherWork(user);
} else {
//log.warn("user is invalid");
}
}
private boolean isUserValid(User user) {
//check user, return false if not valid
// perhaps logging at debug level what's wrong is also helpful
}
这有几点:
- 显式声明使用户无效的原因,可以独立于数据库或数据库框架进行测试。此外,你的代码现在的样子,其他人或你将来的样子,不会直观地知道是什么让用户有效。
- 使用异常进行流控制通常是一个坏主意,也是一种反模式。异常应该是例外的,而不是正常业务逻辑的一部分
- 既然你提到过,你可能想看看 Hibernate Validation 项目来使用基于注解的验证。如果你正在处理一个Spring Web项目,你可以很容易地启用它。但是,我还建议的一件事是,不要在接受表单字段的 Web 或表示层公开您的数据库类/实体。最好使用所谓的数据传输对象来为您处理验证。一旦有效,您就可以从中创建数据库对象以保存到数据库中。
nullable = false
User
例:
public class NewUserForm {
@NotNull
private String username;
}
//validation happens by the caller of this service layer method or before transforming here
public saveUser(NewUserForm userForm) {
User user = transformToUser(userForm);
userRepository.save(user);
}
有关在 Spring 中开始验证的更多信息,您可以 Google 搜索,您会找到大量关于此的“入门”指南。Spring Hibernate Validation
评论
@Column