user825999
user825999

Reputation: 41

JSR 303 - validation multiple inner lists

I am using JSR 303 and have written a number of annotations so I am familiar with the process of getting custom constraints working.

I have just come up against a problem that I am not sure I can solve elegantly. The objects here are for illustration ! So I have a grandparent object which has a list of children. Each child has its own list of children (grandchildren to the grandparent, obviously). The size of this list can be constrained with @Size. But I need to constrain the TOTAL size of the number of (grand)children from the grandparent so that if I validate the Grandparent instance, they are limited to 50 grandchildren across all of their children. Odd example, I know :-)

I started this by creating a method in the grandparent which simply counts all of the elements in the children lists of the children lists in the GrandParent and adding a simple @Size annotation to that. This feels just a little ugly - adding a method like this which is only there to serve some validation. Wasn't that part of what JSR was supposed to solve ?

Or - create a custom annotation like this :

@CustomListSize(listName="children.children", min=0, max=50)
Grandparent
    --> List<Child> children
        @Size(min=0, max=5)
        -->List<Child> children
    --> List<Object> list1
        -->List<Object> list2

I can obviously get this with reflection / propertydescriptor and check against the min / max value. Does that sound OK or is there a better way in JSR 303 that I am missing. This works too but requires more code and is still not ideal.

Finally, what if I wanted to do the same check on the number of entries in list2 ? I can't repeat CustomListSize so how to do that - have an inner list ?

Thanks

Chris

Upvotes: 4

Views: 709

Answers (2)

Balaji Natesan
Balaji Natesan

Reputation: 781

Create a custom validator for Grandparent

public class GrandParentValidator implements ConstraintValidator {

@Override
public boolean isValid(GrandParent bean,
        ConstraintValidatorContext ctx) {            
          //Count the number of Grandkids
          int noOfGrandKids  = 0 ;
          for (Children child :bean.getAllChild() ){
              noOfGrandKids += child.getAllChild().size ;
          }

          if (int noOfGrandKids  > 50){ 
            ctx.disableDefaultConstraintViolation();
            ctx.buildConstraintViolationWithTemplate("Invalid -More than 50 Grandkids found").addConstraintViolation();
            return false ;
          }
         return true ;
      }

}

Upvotes: 0

Piotr Kochański
Piotr Kochański

Reputation: 22672

I think that custom validator for your grandparent object would be a good approach.

@InnerListSize(lists = {"list1", list2"}, min=0, max=50)
class GrandParent{
   List list1;
   List list2;

}

Reflection can be used to get lists. Once we have them it is easy to calculate overall size. The validator class would not be particularly complicated.

Upvotes: 1

Related Questions