Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: Custom constraint vs invalid value reported on nested path
PostPosted: Thu Aug 09, 2012 10:53 am 
Newbie

Joined: Fri Oct 12, 2007 5:18 pm
Posts: 10
Hi,

There's something I've been trying to do and I don't know if it complies with the JSR-303 specifications.

Let's assume the following model:

Code:
@Entity
public class Person {
    // ... some other attributes...
    @Embedded
    private Phone phone;
}

@Entity
public class Company {
    // ... some other attributes...
    @Embedded
    private Phone phone;
}

@Embeddable
public class Phone {
    private String number;
    private String extension;
}


So we have a Person that has a Phone and a Company that also has a Phone. Let's say I want to validate the format of the phone number one way for the Person and another way for the Company, I thought the following would be valid:

Code:
@Target({ METHOD, FIELD, TYPE })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = PhoneConstraintValidator.class)
public @interface PhoneConstraint {
    String message() default "{PhoneConstraint.message}";
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default {};
    PhoneConstraintMode value();
}

public enum PhoneConstraintMode {
    MODE_A, MODE_B
}

public class PhoneConstraintValidator implements ContraintValidator<PhoneConstraint, Phone> {
    private PhoneConstraintMode mode;
    public void initialize(PhoneConstraint phoneConstraint) {
        mode = phoneConstraint.value();
    }

    public boolean isValid(Phone value, ConstraintValidatorContext context) {
        boolean valid = true;
        if (value != null) {
            if (mode == PhoneConstraintMode.MODE_A) {
                if (/*test goes here*/) {
                    valid = false;
                    context.buildConstraintViolationWithTemplate("{PhoneConstraint.MODE_A.message}").addNode("number").addConstraintViolation().disableDefaultConstraintViolation();
                }
            } else if (/*test goes here*/) {
                    valid = false;
                    context.buildConstraintViolationWithTemplate("{PhoneConstraint.MODE_B.message}").addNode("number").addConstraintViolation().disableDefaultConstraintViolation();
                }
            }
        }
        return valid;
    }
}


Then, I would simply place the constraint on the field and use the right mode in each owning entity:

Code:
@Entity
public class Person {
    // ... some other attributes...
    @Embedded
    @PhoneConstraint(PhoneConstraintMode.MODE_A)
    private Phone phone;
}

@Entity
public class Company {
    // ... some other attributes...
    @Embedded
    @PhoneConstraint(PhoneConstraintMode.MODE_B)
    private Phone phone;
}


This works. The property path in the ConstraintViolation is "phone.number" when I validate the Person or the Company, but the invalid value is the whole Phone object and not the invalid number. Wouldn't it make sense that the invalid value reflects the property path of a given ConstraintViolation based on the root bean being validated? I understand that the value validated by the constraint is the Phone as a whole, but if I explicitly disable the default constraint and add a node to the constraint that I'm creating, I thought that the invalid value would match that node path. Or is what I'm trying to do a misuse of the validation API?

Thank you.


Top
 Profile  
 
 Post subject: Re: Custom constraint vs invalid value reported on nested path
PostPosted: Mon Aug 20, 2012 4:43 am 
Hibernate Team
Hibernate Team

Joined: Thu Apr 05, 2007 5:52 am
Posts: 1689
Location: Sweden
hi,

you are right, the invalid value is the Phone instance. The context.buildConstraintViolationWithTemplate allows you to add additional constraint violations where the nodes in question don't even have to exists.

--Hardy


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.