How to disable Hibernate validation in a Spring Boot project
Asked Answered
G

5

54

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!

Goy answered 5/11, 2014 at 18:34 Comment(5)
Add a property to the application.properties file. spring.jpa.properties.javax.persistence.validation.mode=none should do the trick.Konstanze
Worked perfectly, thanks. Is that mentioned in any spring documentation?Goy
How to set additional JPA properties is explained in the reference guide.Konstanze
Oh right, so it is. I missed it because the example appeared to be Hibernate-specific rather than JPA generic, I should have read the paragraphs under the example more carefully.Goy
Just for reference you don't actually need to handle the object being invalid in your controller. If you remove the BindingResult param spring will already throw an MethodArgumentNotValidException by itself. which you can handle nicely in a @ControllerAdvice with an @ExceptionHandler(MethodArgumentNotValidException) method.Eth
G
56

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).

Goy answered 7/11, 2014 at 20:6 Comment(2)
This doesn't work for me in Spring Boot 2.3.5.RELEASEPainting
this disables my @Valid annotation in the controller also... no validation anywhere anymoreJuvenility
N
0

@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
Nuremberg answered 21/10, 2019 at 12:33 Comment(5)
This has to do with whether or not Hibernate will attempt to run DDL statements on your database to create its structure - it has nothing to do with validation...Goy
here if I use the validate option it will compare my Entities with DB tables schemaNuremberg
Yes and that is not the kind of validation that this question addresses. This question is talking about database entity validation (individual records) - not schema validation.Goy
My bad!! didn't understand the question carefully. Anyhow, will edit the answer.Nuremberg
it's not related to validating entitiesHunker
T
0

Actually, in spring boot 2.x. it is:

spring.jpa.hibernate.ddl-auto: none
Timeous answered 13/4, 2020 at 6:59 Comment(2)
spring.jpa.hibernate.ddl-auto relates to hibernate.hbm2ddl.auto which is to do with automatic schema generation, but the question here is related to validating entities.Spinal
@Spinal is correct , it's not related to validating entities.Hunker
L
-1

My project had hibernate-core:5.6. I had to change below property to turn off the schema validation:

spring.jpa.properties.hibernate.hbm2ddl.auto=none
Lounge answered 8/2 at 14:16 Comment(1)
This question is about Entity validation, not Schema validation.Goy
S
-2

for spring boot unless you add validation dependency the spring validation would not kick in.

 <dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-validation</artifactId> 
</dependency>
Secretary answered 4/12, 2020 at 4:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.