[hibernate-issues] [Hibernate-JIRA] Created: (HV-512) Composed constraints lose the payload information of the constraints they are composed of

Geoff The (JIRA) noreply at atlassian.com
Tue Aug 2 14:33:02 EDT 2011


Composed constraints lose the payload information of the constraints they are composed of
-----------------------------------------------------------------------------------------

                 Key: HV-512
                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HV-512
             Project: Hibernate Validator
          Issue Type: Bug
          Components: validators
    Affects Versions: 4.2.0.Final
            Reporter: Geoff The



If a payload is set for child constraints in a composed constraint, their payload values will be ignored.

HV-183 dealt with the propagation of the parent's payload down to the children constraints, but it also overwrites any payload the children may have had.

I would suggest that if the children have any explicit payloads defined, they should be integrated into the parents and not blown away.

{code}
import org.junit.*;

import javax.validation.*;
import javax.validation.constraints.NotNull;

import java.lang.annotation.*;
import java.util.*;

import static org.junit.Assert.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;

public class TestPayload {

    public static class Warning implements Payload {}
    public static class Error implements Payload {}

    @Documented
    @Constraint(validatedBy = NameMustBeGeoffValidator.class)
    @Target({ TYPE, METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
    @Retention(RUNTIME)
    public @interface NameMustBeGeoff {
        String message() default "{NameMustBeGeoff.message}";
        Class<?>[] groups() default {};
        Class<? extends Payload>[] payload() default {};
    }

    public static class NameMustBeGeoffValidator implements ConstraintValidator<NameMustBeGeoff, Customer> {
        @Override
        public void initialize(NameMustBeGeoff constraintAnnotation) {}
        @Override
        public boolean isValid(Customer value, ConstraintValidatorContext context) {
            return ((value.getName() == null) || (value.getName().equals("Geoff")));
        }
    }

    @NameMustBeGeoff(payload = Error.class)
    @Documented
    @Constraint(validatedBy = ValidCustomerValidator.class)
    @Target({ TYPE, METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
    @Retention(RUNTIME)
    public @interface ValidCustomer {
        String message() default "{ValidCustomer.message}";
        Class<?>[] groups() default {};
        Class<? extends Payload>[] payload() default {};
    }

    public static class ValidCustomerValidator implements ConstraintValidator<ValidCustomer, Customer> {
        @Override
        public void initialize(ValidCustomer constraintAnnotation) {}
        @Override
        public boolean isValid(Customer value, ConstraintValidatorContext context) { return true; }
    }

    @ValidCustomer
    public class Customer {
        private String name;

        public Customer(String name) { this.name = name; }

        @NotNull(payload = Warning.class)
        public String getName() { return this.name; }
    }

    /**
     * Customer's name is null, it should trigger the @NotNull with a Warning payload
     */
    @Test
    public void test() {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();

        Customer customer = new Customer(null);

        Set<ConstraintViolation<Customer>> violations = validator.validate(customer);
        assertEquals(1, violations.size());

        ConstraintViolation<Customer> violation = violations.iterator().next();
        assertEquals("may not be null", violation.getMessage());
        assertEquals("javax.validation.constraints.NotNull", violation.getConstraintDescriptor().getAnnotation().annotationType().getName());
        assertEquals(1, violation.getConstraintDescriptor().getPayload().size());
        assertEquals(Warning.class, violation.getConstraintDescriptor().getPayload().iterator().next());
    }

    /**
     * Customer's name is not Geoff and should trigger the NameMustBeGeoff constraint, but the Error payload is lost
     */
    @Test
    public void testPayloadInComposedConstraints() {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();

        Customer customer = new Customer("Bob");

        Set<ConstraintViolation<Customer>> violations = validator.validate(customer);
        assertEquals(1, violations.size());

        ConstraintViolation<Customer> violation = violations.iterator().next();
        assertEquals("{NameMustBeGeoff.message}", violation.getMessage());
        assertEquals("org.geofft.TestPayload$NameMustBeGeoff", violation.getConstraintDescriptor().getAnnotation().annotationType().getName());

        assertEquals(0, violation.getConstraintDescriptor().getPayload().size()); // Not what I expected

        /*

        What I think should happen:

        assertEquals(1, violation.getConstraintDescriptor().getPayload().size());
        assertEquals(Customer.Error.class, violation.getConstraintDescriptor().getPayload().iterator().next());

        */
    }

}
{code}



--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the hibernate-issues mailing list