Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to disable Hibernate validation in a Spring Boot project

I have a spring boot project that has a CrudRepository, an Entity and a Controller. I am basically trying to persist an entity based on the data passed to the Controller.

To do this, I am using spring-boot-starter-jpa. My Entity is annotated with JSR-303 annotations, which are checked in the controller before the data gets passed to the CrudRepository for persistence.

Controller method:

@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:

@Entity /* JPA */ public class User {     @Id /* JPA */    @Column(name="email_address", nullable=false, length=255) /* JPA */    @UserUnique    private String emailAddress;  } 

The cause of my issues is the UserUnique annotation. Its validator looks like this:

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;    } } 

What seems to be happening is, the validation is getting run twice. Once in the controller via the @Valid annotation, and once when Hibernate tries to persist the object. However, when Hibernate tries to persist the object, it throws:

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

This seems to be because its not spring-aware and cant inject the dependency into the constructor. So, what I want to do is disable Hibernate validation completely (as its redundant and already happening in the controller).

There seems to be a property called javax.persistence.validation.mode which you can set to none. However, I cant for the life of me figure out where to set it in a code-based configuration.

I realise there are questions like JSR-303 dependency injection and Hibernate but these are all using xml config and manually configuring parts of the persistence layer.

What I want to do is "post-configure" the required parts of the persistence layer that Spring Boot creates for me because if I define my own then I am no longer leveraging Spring Boot's auto configuration. Can anyone help me determine if 1) this is possible and 2) which parts do I need to configure and how?

Thanks!

like image 396
Erin Drummond Avatar asked Nov 05 '14 18:11

Erin Drummond


People also ask

What is Hibernate validation?

Hibernate Validator allows to express and validate application constraints. The default metadata source are annotations, with the ability to override and extend through the use of XML. It is not tied to a specific application tier or programming model and is available for both server and client application programming.

What is @valid annotation in Spring boot?

The @Valid annotation will tell spring to go and validate the data passed into the controller by checking to see that the integer numberBetweenOneAndTen is between 1 and 10 inclusive because of those min and max annotations.

What is the difference between javax validation and Hibernate Validator?

The Javax bean validation API provides the following most frequently used annotations. The Hibernate validator provides the following commonly used annotations for validation. In case of product or project development we must use both the annotations for bean validation.

What is the use of @valid annotation?

The @Valid annotation ensures the validation of the whole object. Importantly, it performs the validation of the whole object graph. However, this creates issues for scenarios needing only partial validation. On the other hand, we can use @Validated for group validation, including the above partial validation.


2 Answers

As [M. Deinum] mentioned in a comment on my original post, the solution is to set:

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

In the application.properties file.

Additionally, this behaviour is described here (its easy to miss because no example is provided).

like image 61
Erin Drummond Avatar answered Sep 23 '22 05:09

Erin Drummond


@Erin Drummond's Answer is for database entity validation (individual records)

But if someone ran into a problem with schema validation below property works well.

# Hibernate ddl auto (create, create-drop, validate, update, none) spring.jpa.hibernate.ddl-auto=none 
like image 34
Asad Shakeel Avatar answered Sep 23 '22 05:09

Asad Shakeel