我正在尝试为Rest API实现注册控制器.我已经了解了@Transactional的位置. (不是在DAO级别,但在服务可能是精心策划的).在我的用例中,我不仅需要服务,还需要使用hibernate验证来使用相同的事务.
这是控制器的代码:
@Autowired
private UserService userService;
@RequestMapping(method = RequestMethod.GET)
@ResponseBody
@Transactional
public DefaultResponse register(@Valid RegisterIO registerIO, BindingResult errors) {
DefaultResponse result = new DefaultResponse();
if (errors.hasErrors()) {
result.addErrors(errors);
} else {
userService.register(registerIO);
}
return result;
}
我编写了一个自定义约束注释,它验证了参数registerIO的一个属性.这两个验证器和userService.register(registerIO);访问数据库(检查电子邮件地址是否已被使用).
因此,我希望两种方法都使用相同的Hibernate会话和事务.
此方法导致以下异常:
org.hibernate.HibernateException: No Session found for current thread
org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:941)
问题是@Transactional注释.当我将这个注释放在方法中时,调用数据库的一切都可以找到,但是两个事务都是startet.我怀疑当我将它放在寄存器方法时,在@Transactional启动此方法的事务之前执行休眠验证.
我开发了以下功能性解决方法,但我对它不满意.此代码不使用@Valid注释,而是单独调用验证器:
@RequestMapping(method = RequestMethod.GET)
@ResponseBody
@Transactional
public DefaultResponse register( RegisterIO registerIO, BindingResult errors) {
DefaultResponse result = new DefaultResponse();
ValidatorFactory vf = Validation.buildDefaultValidatorFactory();
Validator validator = vf.getValidator();
Set> valResult = validator.validate(registerIO);
我试着总结一下我的问题:
将Spring MVC和Hibernate-Validation与@Valid和@Transactional一起使用,如何将整个请求封装到一个事务中?
谢谢 :)