Skip to main content

Java Validation standard JSR-303

Every application needs to do some validation, and it varies from simple checking on values to complex business rules, like verifying if the user bill has been paid and payment received before we are able to call the print bill API.

 So the java people have created a standard for us under the number JSR-303 that creates a pretty nice way to validate our entities. javax.validatio, inside the validation-api.jar, is the API package for this standard.

The most popular implementation for that API is Hibernate-validator gradle dependencies : compile 'org.hibernate:hibernate-validator:5.0.1.Final'

What mainly is in the validation-api jar are the constraints and the generic interface ConstraintValidator, these are what I'm going to work with here.

there are two methods in this interface the one that does the work is the isValid method, this what will be called, and this what we need to implement  if we need a custom validation rule.

the standard rules are the following :
AssertFalse, AssertTrue, DecimalMax, DecimalMin, Digits, Future, Max, Min, NotNull, Null, Past,
Pattern, Size.

and they are used like this

class MyClass {

private String id;


this is the simplest way of using the validation API, you dont have to do more, just put the hibernate validator in the class path, and instantiate your validator and use it, see this very basic example :
[ it's important that you understand the very basics about validation to continue]

but in most cases we need to tweak things a bit for our business needs. and what we need more is also integrating this to be an autonomous process, and not call validator in every method, unless there is an explicit need for that.

so the way to do that is by using aspects, and the way I like it is on business logic APIs, but it is up to you to choose where you need to put that and I'll explain two ways, but first let's delegate the validator instantiation to the Spring framework

Spring supports the hibernate validator out of the box (the spring jar for this is spring-context.jar)

in our container configuration we add the following:

this will handle creating the validator instance for us.
the messageSource( ) is my custom messages source for i18n purposes, but it's not required by every one since hibernate validator already provide default messages, you can check them out here:

anyway let's proceed with the two possible locations where we can use the validation

1- If we are using Spring dispatcher servlet, we can out of the box put validation on our Rest/MVC controllers

2- On the business logic beans api.

General preparation:

now we add the validation rules to the user entity:

This what you will think at first will be enough, but actually there are couple of problems in this approach..

You see, now the business objects like the User object is no longer a dummy object just to hold data, it has business logic and that logic is in the validation's now part of the API itself so we should use it that way and the best way I found to do that is to create a Business object for each call..

 otherwise, there may be conflicts in validation rules, like in the update method we don't want to validate the password again, it shouldn't be in the user object in the first place, another thing is that we may add another field : passwordConfirmation and validate that it match the password field.

so to correctly place our logic, I prefer to create a Business object for different APIs, example for create API:

and for the update API BO :

this is better, each API has it's own validation rule and does one thing, and does it right.
it's not repetition as it may seem, these are totally different APIs and each has it's own work, but it all comes down to your business logic.

To implement the rule that the password and passwordConfirmation should be the same, we should do that with custom validation annotation.

and the validator :

and based on this our BO :

Note that the last rule is put on the validated class instead of the field and the constraint validator takes Object as the class parameter.

Now regarding where to tell Spring to validate an object or not:

Option #1 - validate on web tier

Spring people like everything to be done on the controller level and they have their reasons and I can think one reason like:

what to do if business services call each other, should we validate or assume we are working with validated data?

Assume our controller will look like this without validation:

Reminder: make sure you provide the validator( ) bean with the same name, don't change it to something like : beanValidator( ) since Spring won't be happy.

What we need to do to tell spring to validate the objects is to add @Valid annotation

Spring will throw MethodArgumentNotValidException [ this is a custom spring exception ] in case of invalid objects, you can handle this exception using @ExceptionHandler annotation, I'll do another blog about ExceptionHandling.

Option#2- Validation on BL

To validate on Business layer API we need use aspects, to do that we need to register a bean MethodValidationPostProcessor :

and to trigger the validation we need to do 2 things

1- add @Valid annotation to the method parameters
2- add @Validated to the class/interface we are calling

this will throw ConstraintViolationException [original exception by validation-api]

here is how I handle this and convert it into my custom object :


Database validation

You can use the custom ConstraintValidator to communicate with spring beans, it will do that by default if you use validation on Controller layer, but in case of method validator [BL layer], make sure to register the beans correctly.

here is an example of my code using bean to validate object:

Rules Order can be defined by the annotation @GroupSequence

and that's all you can gracefully start using the validation-api JSR-303


  1. Thank you for this great article.

    I just have a problem with MethodValidationPostProcessor: if my Controller calls a bean annotated with @Transactional, the annotation is no longer handled and no transaction is created.

    It is an annoying side effect, do you have a work around ?

    Thanks !


Post a Comment

Popular posts from this blog

Spring 4 + Hibernate 4 / Java configuration / rest service example with gradle

In this post I'll explain the required work to create a rest API utilizing both spring and hibernate version 4, and the configuration will be using java configuration classes not XML. I'll use gradle to build and for dependency management, it's way easier than maven and keeps you focused on the application, if you are not familiar with gradle and interested in it see my previous post about it. The first part which is dependency management is covered in gradle post mentioned above. I'll skip to explain each tier of the project and its configurations: As you can see we have 4 tiers: 1) DAO tier / data tier In this tier we configure the datasource and hibernate, I used HSQL in memory db it can be easily substituted with other db engine providing the right dependencies The DaoConfig defines the data source, transaction manager, session factory and  hibernate properties The most important part is the annotations : 1)  @Configuration  : to tell spring th

Android RecyclerView - Adding Empty View

So RecyclerView was introduced to replace List view and it's optimized to reuse existing views and so it's faster and more efficient as stated in the documentation: While using it, I faced the issue of missing a useful functionality that is implemented in ListView. that feature is setting an empty view in case there was no records. In ListView it was as simple as this View emptyView = findViewById(; ListView  myList = .... myList.setEmptyView(emptyView); but this method doesn't exist for recycler view so we need a work around until android team fixes this. and here are the screen shots of both list view and recycler view fix List view : Recycler view : here is how I fixed it: here is the content of empty_view, it can be anything. Enjoy.

[PART 5] NuTracker ReactJS app - Add Login & Profile using Router

In the previous part we finished the dashboard read functionality, now we want to add the skeleton for other pages: - Login   In this page the user will be able to login to their account and the dashboard won't show unless the user is logged in. - Profile In this page the user will be able to update their daily nutrition goals that they can track in the dashboard. to be able to have multiple 'pages' in react and navigate from one to one, we need something that can switch the rendered content based on what we want, we can do that with if statements in the App components and store some location state, but why invent the wheel. React Router every major single page app web framework has the routing concept and functionality to interact with the usual browser urls and switch the content based what user should see. for example on the profile page I want the url path to be /profile, and for login to be /login and so on. in more advanced cases you want the users