[bv-dev] BVAL-221 Constraint violation builder cannot put constraint on a top level map key

Emmanuel Bernard emmanuel at hibernate.org
Tue Dec 4 10:42:06 EST 2012


These are good questions

## Natural way to do it?

Assuming

@HasCorrectHomeAddressFromTop
class Order {
  @HasCorrectHomeAddressFromUser
  User user;
}

class User {
  @CollectionNotEmpty
  @HasCorrectHomeAddressFromAddresses
  Map<String,Address> addresses;
}

When `HasCorrectHomeAddressFromTop` is validated, you can attach a
`ConstraintViolation` to Order.user.addresses["home"] with the
following call and it works in BV 1.0
This is how the API is supposed to be used.

    context.buildConstraintViolationWithTemplate( "Incorrect home address" )
        .addNode( "user" )
        .addNode( "addresses" )
            .inIterable().atKey( "home" )
        .addConstraintViolation();

following this logic, when `HasCorrectHomeAddressFromUser` is validated,
you can attach a `ConstraintViolation` with the following call but that
does not work in BV 1.0.

    context.buildConstraintViolationWithTemplate( "Incorrect home address" )
        .addNode( "addresses" )
            .inIterable().atKey( "home" )
        .addConstraintViolation();

When `HasCorrectHomeAddressFromAddresses` is validated, you can attach a
`ConstraintViolation` with the following call but that does not work
in BV 1.0.

    context.buildConstraintViolationWithTemplate( "Incorrect home address" )
        .addNode( null )
            .inIterable().atKey( "home" )
        .addConstraintViolation();

Not that we use null as we add a class level constraint violation to the
element in `addresses["home"]`.

For you info, when `CollectionNotEmpty` is validated, you can attach a
`ConstraintViolation` with the following call.

    context.buildConstraintViolationWithTemplate( "collection empty" )
        .addConstraintViolation();

## Loss in type-safety

If we add `inIterable()` to `NodeBuilderDefinedContext` we solve our
problem but we introduce a leak in the type safety. I could do the
following calls

    context.buildConstraintViolationWithTemplate( "Incorrect home address" )
        .addNode( null )
            .inIterable().atKey( "home" )
                .inIterable().atKey( "wc" )
            .addConstraintViolation();

This call is not correct as no node has been (explicitly) created
between the two inIterable() calls. The correct call would be

    context.buildConstraintViolationWithTemplate( "Incorrect WC location" )
        .addNode( null )
            .inIterable().atKey( "home" )
        .addNode( null )
            .inIterable().atKey( "wc" )
        .addConstraintViolation();

Here we are assuming that the `addresses` elements contain map.

We could add in the spec that subsequent calls to `inIterable()`
implicitly create a node without name.

The problem is not as critical as I imagined but that would require
adding some magic rules wrt node creation.

Also imagine a user willing to validate a property of Address, could he
forget to call the node creation method?

Emmanuel

On Mon 2012-11-26 13:07, Hardy Ferentschik wrote:
> 
> On 23 Jan 2012, at 2:48 PM, Emmanuel Bernard <emmanuel at hibernate.org> wrote:
> 
> > The question is do we want to do that or lean towards one of the
> > alternative methods:
> > 
> > - an explicit new method deprecating addNode
> > - relaxing NodeBuilderDefinedContext and adding the new contract on it
> 
> In the proposal you are saying about relaxing NodeBuilderDefinedContext:  "But that would break the contextual 
> and safety of the API as this interface is also returned by atKey and atIndex." 
> Can you provide an example?
> 
> Also in the proposal you are saying that:
> 
> context.buildConstraintViolationWithTemplate("oh noes")
>         .addNode(null) //ie the contained element
>             inIterable().atKey(someKey)
>         .addConstraintViolation();
> 
> would be the natural solution. Why is ".addNode(null)" natural and why could we not have inIterable() directly 
> on ConstraintViolationBuilder?
> 
> --Hardy
> 
> 
> _______________________________________________
> beanvalidation-dev mailing list
> beanvalidation-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/beanvalidation-dev


More information about the beanvalidation-dev mailing list