我想实现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;
}
我写了定制contraint注解,这验证了参数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启动此方法的事务之前执行hibernate验证。
我开发了以下功能解决方法,但我不满意。这个代码不使用@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<ConstraintViolation<RegisterIO>> valResult = validator.validate(registerIO);
我试着总结一下我的问题: 使用Spring MVC和Hibernate验证与@Valid和@Transactional在一起,怎么可能将整个请求封装到一个事务中?
谢谢:)
您使用的是JSR 330验证吗? –
JSR 330:Java的依赖注入:我使用Spring进行依赖注入。 @Autowire在这种情况下工作正常。我不确定你的意思是JSR 303:Bean验证:这里我使用Hibernate-Validator 4.3.1实现 – Sebastian
回答这个问题。 Hibernate Validator是Bean Validation(JSR 330)规范的参考实现。 – Hardy