-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 
Author Message
 Post subject: @ValidateReference in Validation...
PostPosted: Wed Jul 15, 2015 11:42 am 
Newbie

Joined: Thu May 21, 2015 11:19 am
Posts: 7
Hello,
I have 2 models in my architecture, model 1 is the bean that represents the data in my html form. Model 2 represents that data that is stored in the database. In this case I'll call UserBean the model from the html form and User represents the model object to be stored in the database. UserBean uses User to retrieve user data such as name and email. Keeping in mind DRY (Don't repeat yourself) I'd like to annotate my User object and have the UserBean object reference the User object's annotated types -- see the @ValidateReference constraint annotation below.

I have a UserBean and User class that looks like this

Code:
public class UserBean {

    private User user = new User();

    @ValidateReference(refClass=User.class, property = "name")
    public String getName() {
        return user.getName();
    }

    public void setName(String name) {
        this.user.setName( name);
    }

    @ValidateReference(refClass=User.class, property = "email")
    public String getEmail() {
        return user.getEmail();
    }
    public void setEmail(String email) {
        this.user.setEmail(email);
    }
    public User getUser() { return user; }
}

//======================================================
public class User
{
   private String name;
   private String email;

   @Size(min = 3, message = "Name should at least be 3 characters long")
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
   @Pattern(regexp = "^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$", message = "This is not a valid email")
   public String getEmail() {
      return email;
   }
   public void setEmail(String email) {
      this.email = email;
   }
}

I created the following constraint annotation ValidateReference and ValidateReferenceValidator. My question is, how do I get access to the Locale inside the ValidateReferenceValidator class as well as fill in all the error message information so the error in the actual annotation constraint bubbles up to the final output error message? I sense I'm going down the wrong path in this solution. Please suggest a better path if necessary.

Code:
@Target({TYPE, METHOD, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = ValidateReferenceValidator.class)
@Documented
public @interface ValidateReference
{
   String message() default "message from ValidateReference";
   Class<?> refClass() ;
   String property() ;
   Class<?>[] groups() default {};
   Class<? extends Payload>[] payload() default {};
}

=======================================================

public class ValidateReferenceValidator implements ConstraintValidator<ValidateReference, Object>
{
   Class<?> theClass;
   String property;
   Class<?>[] groups;

   public void initialize(ValidateReference validateReference)
   {
      theClass = validateReference.refClass();
      property = validateReference.property();
      groups = validateReference.groups();
                // I need help in here to get the Locale information or possibly in the method below.
   }

   public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext)
   {
      HibernateConstraintValidatorContext hibernateContext =
            constraintValidatorContext.unwrap( HibernateConstraintValidatorContext.class );

      Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
      Set<? extends ConstraintViolation<?>> results = validator.validateValue(theClass, property, o, groups);
      if (!results.isEmpty())
      {
                        // I need help in here to fill in all the error data from the actual constraint annotations that failed.
         return false;
      }
      return true;
   }
}


Top
 Profile  
 
 Post subject: Re: @ValidateReference in Validation...
PostPosted: Tue Jul 28, 2015 2:54 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
For your locale question, here is an example from the spec: http://beanvalidation.org/1.1/spec/#validationapi-message-examples
That's the approach sued by JSF and other web frameworks.

How to pass the locale in your validator is a different story, I think you might have to use a thread local variable. There is a proposal floating around to pass random objects to a validator but it's not implemented yet.

On the larger picture, we usually recommend not to have separate object for essentially the same structure (User and UserForm). Rather, we recommend that the User object be used to store the form data. That's how JSF and a few other web framework do it. They make use of an interesting feature of Bean Validation, which is to validate a given property value if it were to be changed.

Code:
validator.validateValue(User.class, "name", nameValue);

_________________
Emmanuel


Top
 Profile  
 
 Post subject: Re: @ValidateReference in Validation...
PostPosted: Tue Jul 28, 2015 3:27 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
An Gunnar's proposal on your cross post is more generic and valid. It requires more work though.
https://forum.hibernate.org/viewtopic.php?f=9&t=1040703&p=2486063#p2486063

_________________
Emmanuel


Top
 Profile  
 
 Post subject: Re: @ValidateReference in Validation...
PostPosted: Tue Jul 28, 2015 10:05 am 
Hibernate Team
Hibernate Team

Joined: Sat Jan 24, 2009 12:46 pm
Posts: 388
Hi,

As in my answer to your other question here https://forum.hibernate.org/viewtopic.php?f=26&t=1040725 I think you are best off by propagating the constraints from one model to the other by querying the BV metadata API and using the HV API for programmatic constraint declaration to create the constraints in the other model.

I've filed https://hibernate.atlassian.net/browse/HV-1008 for establishing a more high-level means for that in Hibernate Validator as a first step.

Cheers,

--Gunnar

_________________
Visit my blog at http://musingsofaprogrammingaddict.blogspot.com/


Top
 Profile  
 
 Post subject: Re: @ValidateReference in Validation...
PostPosted: Tue Jul 28, 2015 4:45 pm 
Newbie

Joined: Thu May 21, 2015 11:19 am
Posts: 7
Thanks! It will be great to see @ValidateReference (or @ValidateValue since its behavior is similar to validate.validateValue(...)) functionality in the future. In the meantime, validate.validateValue(...) seems to be the best solution.

Thanks!
James


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 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.