Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 3 posts ] 
Author Message
 Post subject: Validation for complex object
PostPosted: Wed Apr 13, 2016 8:00 pm 
Newbie

Joined: Wed May 11, 2011 7:40 pm
Posts: 4
Newbie question around hibernate validator. I have 2 classes, which have reference to another child class and depending on parent class validation on child class should change. Looking at documentation it seem like I should use SequenceProvider so I create sequence provider for each parent class and than groups for including appropriate validations on child class but it doesn't seem to work.

So here are my questions -
1) Is this correct approach? or should I use something else
2) What am I missing if this is right approach

UserCreate Class -
Code:
@GroupSequenceProvider(CreateUserGroupSequenceProvider.class)
public class CreateUserRequest {
    @Valid
    @NotNull
    protected IdentityRequest identity;

    @Valid
    protected RegistrationProfileRequest registrationProfile;

    @Valid
    protected ProfileRequest profile;
}


UserUpdate Class -

Code:
@GroupSequenceProvider(UpdateUserGroupSequenceProvider.class)
public class UpdateUserRequest {

    @Valid
    protected IdentityRequest identity;

    @Valid
    protected RegistrationProfileRequest registrationProfile;

    @Valid
    protected ProfileRequest profile;
}


And here is the child class ex: IdentityRequest -

Code:
public class IdentityRequest {

    @NotNull(groups = CreateIdentityValidation.class, message = "Invalid email")
    @Email(regexp = "(.+@[a-zA-Z0-9-.]+\\.[a-zA-Z0-9-.]+)", groups = {CreateIdentityValidation.class, EmailValidation.class}, message = "Invalid email")
    @SafeHtml(whitelistType = NONE, groups = {CreateIdentityValidation.class, EmailValidation.class}, message = "Invalid email")
    private String email;

    @NotNull(groups = {CreateIdentityValidation.class, PasswordValidation.class}, message = "Invalid password")
    @Size(min = 8, max = 255, groups = {CreateIdentityValidation.class, PasswordValidation.class}, message = "Invalid password")
    private String password;
}


So I have created 2 sequence provider one for each Create and Update request. And than in IdentityRequest for each validation I have assigned groups.

For ex: When Parent = CreateRequest than email and password both are required whereas when UpdateRequest its optional.

CreateUserGroupSequenceProvider
Code:
public class CreateUserGroupSequenceProvider implements DefaultGroupSequenceProvider<CreateUserRequest> {

    @Override
    public List<Class<?>> getValidationGroups(CreateUserRequest createUserRequest) {
        List<Class<?>> defaultGroupSequence = new ArrayList();
        defaultGroupSequence.add(createUserRequest.class);

        if (createUserRequest != null) {
            addIdentityValidationGroups(defaultGroupSequence, createUserRequest.getIdentity());

            addRegistrationProfileValidationGroups(defaultGroupSequence, createUserRequest.getRegistrationProfile());

            addProfileValidationGroups(defaultGroupSequence, createUserRequest.getProfile());
        }

        return defaultGroupSequence;
    }

    @Override
    protected void addIdentityValidationGroups(List<Class<?>> defaultGroupSequence, IdentityRequest identityRequest) {
        //validation group for username/password
        defaultGroupSequence.add(CreateIdentityValidation.class);
    }
}


UpdateUserGroupSequenceProvider

Code:
public class UpdateUserGroupSequenceProvider implements DefaultGroupSequenceProvider<UpdateUserRequest> {

    @Override
    public List<Class<?>> getValidationGroups(UpdateUserRequest updateUserRequest) {
        List<Class<?>> defaultGroupSequence = new ArrayList();
        defaultGroupSequence.add(UpdateUserRequest.class);

        if (updateUserRequest != null) {
            addIdentityValidationGroups(defaultGroupSequence, updateUserRequest.getIdentity());

            addRegistrationProfileValidationGroups(defaultGroupSequence, updateUserRequest.getRegistrationProfile());

            addProfileValidationGroups(defaultGroupSequence, updateUserRequest.getProfile());
        }

        return defaultGroupSequence;
    }
   
    @Override
    protected void addIdentityValidationGroups(List<Class<?>> defaultGroupSequence, IdentityRequest identityRequest) {
        if (identityRequest != null) {
            //Add password validation
            if (identityRequest.getPassword() != null) {
                defaultGroupSequence.add(IdentityValidation.PasswordValidation.class);
            }
            //Add email validation
            if (identityRequest.getEmail() != null) {
                defaultGroupSequence.add(IdentityValidation.EmailValidation.class);
            }
        }
    }
}



Top
 Profile  
 
 Post subject: Re: Validation for complex object
PostPosted: Thu Apr 14, 2016 7:02 pm 
Newbie

Joined: Wed May 11, 2011 7:40 pm
Posts: 4
Any help would be greatly appreciated. Even after debugging a lot I am unclear on how to proceed forward, it seems to skip email/password validation for UpdateRequest and narrowed it down to below Class and snippet of code -

Hibernate Validator Version = 5.2.2.Final

ValidatorImpl.java: Line 1504

Code:
if ( !metaConstraint.getGroupList().contains( valueContext.getCurrentGroup() ) ) {
         return false;
      }


metaConstraint.getGroupList() = FirstNameValidation
valueContext.getCurrentGroup() = Default

As per SequenceProvider documentation it seems like all the validations are added to "Default" group. I am assuming that I am not doing this right way.

If I write unit test which invoke validator with groupName = FirstNameValidation.class than those validations work but I am using spring-boot and I hope just adding @Valid on this object will trigger those validation.


Top
 Profile  
 
 Post subject: Re: Validation for complex object
PostPosted: Mon Apr 18, 2016 4:05 am 
Hibernate Team
Hibernate Team

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

You could use group conversion (see http://beanvalidation.org/1.1/spec/#con ... conversion) for this. The idea would be to tanslate the default group into a specific group for insert or update for the two different references to IdentityRequest. E.g.:

Code:
public class CreateUserRequest {
    @Valid
    @NotNull
    @ConvertGroup(from=Default.class, to=CreateConstraints.class)
    protected IdentityRequest identity;
}


Hth,

--Gunnar

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


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 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.