【问题标题】:How to disable Hibernate validation in a Spring Boot project如何在 Spring Boot 项目中禁用 Hibernate 验证
【发布时间】:2015-01-02 01:52:01
【问题描述】:

我有一个 Spring Boot 项目,它有一个 CrudRepository、一个实体和一个控制器。我基本上是在尝试根据传递给控制器​​的数据来持久化一个实体。

为此,我使用spring-boot-starter-jpa。我的实体使用 JSR-303 注释进行注释,这些注释在控制器中进行检查数据被传递到 CrudRepository 以进行持久性。

控制器方法:

@RequestMapping(value = "users", method = { RequestMethod.POST })
public SuccessfulResponse<User> addUser(@Valid @RequestBody User user, BindingResult validation) {
    if (validation.hasErrors()) {
        throw new ValidationException(validation);
    }
    User saved = this.users.save(user);
    return new SuccessfulResponse<User>(saved);
}

实体:

@Entity /* JPA */
public class User {

   @Id /* JPA */
   @Column(name="email_address", nullable=false, length=255) /* JPA */
   @UserUnique
   private String emailAddress;

}

我的问题的原因是UserUnique 注释。它的验证器如下所示:

public class UserUniqueValidator implements ConstraintValidator<UserUnique, String> {

   private UserRepository users;

   @Autowired
   public UserUniqueValidator(UserRepository users) {
       this.users = users;
   }

   @Override
   public void initialize(UserUnique annotation) {}

   @Override
   public boolean isValid(String value, ConstraintValidatorContext context) {
       return users.findOne(value) == null;
   }
}

似乎正在发生的是,验证运行了两次。一次通过@Valid 注释进入控制器,一次当Hibernate 尝试持久化对象时。但是,当 Hibernate 尝试持久化对象时,它会抛出:

javax.validation.ValidationException: HV000064: Unable to instantiate ConstraintValidator: class test.UserUniqueValidator`

这似乎是因为它不支持弹簧并且无法将依赖项注入构造函数。所以,我想做的是完全禁用 Hibernate 验证(因为它是多余的并且已经在控制器中发生)。

似乎有一个名为javax.persistence.validation.mode 的属性,您可以将其设置为none。但是,我终其一生都无法弄清楚在基于代码的配置中设置它的位置。

我知道有像JSR-303 dependency injection and Hibernate 这样的问题,但这些都是使用 xml 配置和手动配置持久层的一部分。

我想要做的是“后配置”Spring Boot 为我创建的持久层的必需部分,因为如果我自己定义,那么我将不再利用 Spring Boot 的自动配置。谁能帮我确定 1) 这是否可行以及 2) 我需要配置哪些部分以及如何配置?

谢谢!

【问题讨论】:

  • 将属性添加到application.properties 文件。 spring.jpa.properties.javax.persistence.validation.mode=none 应该可以解决问题。
  • 完美运行,谢谢。在任何春季文档中都提到过吗?
  • 参考指南中解释了如何设置额外的 JPA 属性。
  • 哦,对了,就是这样。我错过了它,因为该示例似乎是特定于 Hibernate 而不是 JPA 通用的,我应该更仔细地阅读示例下的段落。
  • 仅供参考,您实际上不需要处理控制器中无效的对象。如果您删除 BindingResult 参数,spring 本身已经抛出 MethodArgumentNotValidException。您可以使用 @ExceptionHandler(MethodArgumentNotValidException) 方法在 @ControllerAdvice 中很好地处理它。

标签: java hibernate jpa spring-boot bean-validation


【解决方案1】:

对于 Spring Boot,除非您添加验证依赖项,否则 Spring 验证不会启动。

 <dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-validation</artifactId> 
</dependency>

【讨论】:

    【解决方案2】:

    实际上,在 spring boot 2.x 中。它是:

    spring.jpa.hibernate.ddl-auto: none
    

    【讨论】:

    • spring.jpa.hibernate.ddl-auto relates to hibernate.hbm2ddl.auto 这与自动模式生成有关,但这里的问题与验证实体有关。
    【解决方案3】:

    @Erin Drummond's Answer 用于数据库实体验证(单个记录)

    但如果有人遇到模式验证的问题,下面的属性会很好。

    # Hibernate ddl auto (create, create-drop, validate, update, none)
    spring.jpa.hibernate.ddl-auto=none
    

    【讨论】:

    • 这与 Hibernate 是否会尝试在您的数据库上运行 DDL 语句以创建其结构有关 - 它与验证无关......
    • 这里如果我使用validate 选项,它会将我的实体与数据库表架构进行比较
    • 是的,这不是这个问题所解决的那种验证。这个问题是关于数据库 entity 验证(单个记录) - 而不是 schema 验证。
    • 我的错!!没有仔细理解这个问题。无论如何,将编辑答案。
    【解决方案4】:

    作为 [M. Deinum]在我原帖的评论中提到,解决方法是设置:

    spring.jpa.properties.javax.persistence.validation.mode=none
    

    application.properties 文件中。

    此外,这种行为是described here(很容易错过,因为没有提供示例)。

    【讨论】:

    • 这在 Spring Boot 2.3.5.RELEASE 中对我不起作用
    • 这也会在控制器中禁用我的@Valid 注释...不再进行任何验证
    猜你喜欢
    • 2019-01-19
    • 1970-01-01
    • 2023-02-03
    • 2017-05-15
    • 2020-09-25
    • 2017-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多