56

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!

5
  • 19
    Add a property to the application.properties file. spring.jpa.properties.javax.persistence.validation.mode=none should do the trick. Commented Nov 6, 2014 at 7:00
  • Worked perfectly, thanks. Is that mentioned in any spring documentation? Commented Nov 7, 2014 at 20:04
  • How to set additional JPA properties is explained in the reference guide. Commented Nov 9, 2014 at 15:01
  • 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. Commented Nov 9, 2014 at 19:55
  • 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. Commented Jul 11, 2016 at 14:09

5 Answers 5

57

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

Sign up to request clarification or add additional context in comments.

2 Comments

This doesn't work for me in Spring Boot 2.3.5.RELEASE
this disables my @Valid annotation in the controller also... no validation anywhere anymore
1

@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

5 Comments

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...
here if I use the validate option it will compare my Entities with DB tables schema
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.
My bad!! didn't understand the question carefully. Anyhow, will edit the answer.
it's not related to validating entities
0

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

spring.jpa.hibernate.ddl-auto: none

2 Comments

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.
@Theozaurus is correct , it's not related to validating entities.
-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

1 Comment

This question is about Entity validation, not Schema validation.
-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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.