Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Bean Validation (JSR303) constraints involving relationship between several bean properties

Tags:

Say I have the following simple java bean:

class MyBean {    private Date startDate;    private Date endDate;    //setter, getters etc... } 

Is there a mechanism in JSR 303 to create a custom validator that validates the constraint that startDate must be before endDate?

It seems to me to be a common use case, yet I cannot find any examples of this kind of multiple property relationsship constraint.

like image 938
Hedenius Access Avatar asked Nov 09 '09 10:11

Hedenius Access


People also ask

How does Java Bean validation work?

The Bean Validation API is a Java specification which is used to apply constraints on object model via annotations. Here, we can validate a length, number, regular expression, etc. Apart from that, we can also provide custom validations. As Bean Validation API is just a specification, it requires an implementation.

How can you explain Bean validation?

JavaBeans Validation (Bean Validation) is a new validation model available as part of Java EE 6 platform. The Bean Validation model is supported by constraints in the form of annotations placed on a field, method, or class of a JavaBeans component, such as a managed bean. Constraints can be built in or user defined.

What does javax validation constraints NotNull do?

@NotNull validates that the annotated property value is not null. @AssertTrue validates that the annotated property value is true.

What is jsr303?

JSR-303 bean validation is an specification whose objective is to standardize the validation of Java beans through annotations. The objective of the JSR-303 standard is to use annotations directly in a Java bean class.


2 Answers

I can think of a few things to try.

You could create a Constraint with a target of the type itself with an appropriate validator:

@ValidateDateRange(start="startDate", end="endDate") public class MyBean { 

You could encapsulate a date range in a type and validate that:

public class DateRange {       private long start;   private long end;    public void setStart(Date start) {     this.start = start.getTime();   }    // etc. 

You could add a simple property that performs the check:

public class MyBean {   private Date startDate;   private Date endDate;    @AssertTrue public boolean isValidRange() {     // TODO: null checks     return endDate.compareTo(startDate) >= 0;   } 
like image 132
McDowell Avatar answered Sep 21 '22 16:09

McDowell


If you're using Hibernate Validator in version 4.1 or later you can use the @ScriptAssert constraint together with a scripting or expression language to express this kind of constraint. Using JavaScript your example would look like this:

 @ScriptAssert(lang = "javascript", script = "_this.startDate.before(_this.endDate)")  public class CalendarEvent {        private Date startDate;        private Date endDate;        //...  }  

You can get an even more compact syntax by creating a custom constraint for the script language of your choice:

@JexlAssert("_.startDate < _.endDate") public class CalendarEvent {      private Date startDate;      private Date endDate;      //... } 
like image 43
Gunnar Avatar answered Sep 21 '22 16:09

Gunnar