java - Hibernate 验证和 Spring Controller 的一个事务

标签 java spring-mvc hibernate-validator transactional hibernate-4.x

我正在尝试为 Rest API 实现注册 Controller 。我已经阅读了很多关于放置@Transactional 的内容。 (不是在 DAO 层面,而是在服务层面可能是精心编排的)。在我的用例中,我不仅需要服务,还需要 hibernate 验证来使用相同的事务。

这是 Controller 的代码:

@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 的一个属性。这个 validator 和 userService.register(registerIO);访问数据库(检查电子邮件地址是否已被使用)。

因此我希望这两种方法都使用相同的 Hibernate session 和事务。

这种方法会导致以下异常:

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 注释。当我将此注释放置在女巫调用数据库的方法时,一切正常,但两个事务已启动。我怀疑当我将它放在 register 方法时, hibernate 验证是在 @Transactional 开始此方法的事务之前执行的。

我开发了以下功能解决方法,但我对此并不满意。这段代码不使用@Valid 注解而是自己调用 validator :

@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-Validation 与 @Valid 和 @Transactional 一起使用,如何将整个请求封装到一个事务中?

谢谢你:)

最佳答案

可以通过使用单个 validator 并将其注入(inject) Controller 来改进您的解决方法。你试过吗:

@Autowired
private Validator validator;

这样您就可以跳过为每个请求创建 validator 的开销。 您还应该注意竞争条件。当您检查数据库是否存在给定电子邮件时,另一个请求可以创建此记录,因此您在插入数据时仍然会遇到异常。

关于java - Hibernate 验证和 Spring Controller 的一个事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16659146/

相关文章:

jsf - 使用 <rich :beanValidator/> 显示自定义转换错误消息

spring - 在 Tomcat 6 中部署 Spring 4.0 时出现 AbstractMethodError

java - Torrent 库允许下载单独的文件片段

java - 带有配置文件的 Spring 集成测试

spring-boot - 当 Spring Boot 应用程序启动时,JSR-303 注释不会验证 bean 属性

java - 一个 Controller 方法中的 Bean

java - 在 spring-mvc 应用程序开始时运行一个类

java - 消息、处理程序和线程 : Lego Mindstorms bluetooth communication

java - MappingException : Invalid path reference club. 名称!关联只能直接指向或通过其 id 属性指向

java - 线程池执行器具有优先任务并避免饥饿