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!
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.
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.
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.
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.
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).
@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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With