7 Replies Latest reply on Apr 28, 2009 1:27 PM by x-files

    Hibernate constraints not checked when using custom JSF validator

    tom.angelo.veltens.1und1.de

      Hello,


      i have wrapped my input fields in a
      <s:validateAll>
      Tag so that the hibernate contraints are being checked. This works fine for all of my inputs but one: The email field has defined a custom jsf validator like this: validator="emailValidator"


      This emailValidator works fine (it verifies if the email is unique), but the email property of my Entity is annotated with @Email from hibernate validation. This annotation is ignored by JSF. It does not validate against it! Only hibernate throws an exception at persist time, which is too late. If I leave out the "validator=..." hibernate validation works, but of course my own JSF validator is not called...


      How can I display both, hibernate validation and jsf validation failures?


      Thanks in advance!

        • 1. Re: Hibernate constraints not checked when using custom JSF validator
          gjeudy

          Why do you need both a JSF validator and hibernate validator for your email field ? The intent of Seam integration with hibernate validator is to declare the constraint once (as an annotation on the entity) and potentially invoke hibernate validator from different layers.


          I don't think Seam supports a scenario where you can have both s:validate and a custom JSF validator on the same field because it goes against the design philosophy of this feature.

          • 2. Re: Hibernate constraints not checked when using custom JSF validator
            tom.angelo.veltens.1und1.de

            I thought the hibernate validators are used to validate against database contraints whereas business validations should be performed in JSF validators. This is my JSF-Validator:



            
            public void validate(FacesContext context, UIComponent component,
                           Object value) throws ValidatorException {
                      
                 UserHome userHome = (UserHome) Component.getInstance("userHome");
            
                 /* verify type of the form data */
                      
                 if (value==null || !(value instanceof String) || ((String)value).length()==0) {
                      FacesMessage message = new FacesMessage();
                      message.setDetail("Email must be a valid string.");
                      message.setSeverity(FacesMessage.SEVERITY_ERROR);
                      throw new ConverterException(message);
                 }
                      
                 /* check for duplicates in the database */
                      
                 if (userHome.findUser(email)!=null) {
                      FacesMessage message = new FacesMessage();
                      message.setDetail("A user with this email address already exists.");
                      message.setSeverity(FacesMessage.SEVERITY_ERROR);
                      throw new ValidatorException(message);
                 }
            
            }
            



            I do not cling to it, if it can be done with a hibernate validator too. But I have no idea how, because my hibernate entities must not depend on Seam components. If you have a solution for a proper hibernate validator please post :-)


            Thanks a lot and kind regards.

            • 3. Re: Hibernate constraints not checked when using custom JSF validator
              tom.angelo.veltens.1und1.de

              Sorry, one line got lost while copypasting...




                   
                   /* check for duplicates in the database */
              



              String email = (String) value;
              



                   
                   
                   if (userHome.findUser(email)!=null) {
                        FacesMessage message = new FacesMessage();
                        message.setDetail("A user with this email address already exists.");
                        message.setSeverity(FacesMessage.SEVERITY_ERROR);
                        throw new ValidatorException(message);
                   }
              
              }
              




              • 4. Re: Hibernate constraints not checked when using custom JSF validator
                barakka

                Hi,


                from the code of your validator it looks like you are evaluating a unique constraint. So why don't you use the unique property of Column annotation? Is it because you need it for live validation?


                Best,
                Riccardo.

                • 5. Re: Hibernate constraints not checked when using custom JSF validator
                  tom.angelo.veltens.1und1.de

                  Yes, i have a unique contraint on my entity, but there is no @Unique hibernate validator or something. Hibernate will throw an exception when persiting a dublicate value, but there is no real validation as @Length, @Email and so on that is done by JSF. So I wrote my own JSF validator...


                  Kind regards.

                  • 6. Re: Hibernate constraints not checked when using custom JSF validator
                    gjeudy

                    You have a good point, I also use JSF validators to database validation (database lookups) because hibernate validator is limited to check at the field level and i'm not sure it fares well when a database lookup is needed. Hopefully this will improve when JSR 303 Bean Validations is implemented by hibernate validator.


                    You can still try to implement your own custom hibernate validator that would merge @Email hibernate validator format check with the database check you have in your JSF validator.


                    Like you mentioned hibernate validator is invoked both from s:validateAll and when the entity is persisted to database. On 2nd though perhaps you don't want a database lookup being done twice for performance reasons.


                    Worst case you can invoke EmailValidator logic from your JSF validator and remove altogether the @Email annotation. This has the drawback of lifting validation at the DAO layer but unless your DAO is shared across many UIs I don't see this as a major problem.

                    • 7. Re: Hibernate constraints not checked when using custom JSF validator

                      Need to implement custom hibernate annotation that contains bussiness logic:



                      @Pattern(regex="^[a-zA-Z0-9_-]{5,20}$", message="#{messages['user.INVALID_USERNAME']}")
                      @UserName(message="#{messages['registration.LOGIN_INAVAILABLE']}")
                      @Column(unique=true, nullable=false, length=20)
                      



                      @UserName - custom hibernate validator


                      For more details see please:
                      http://reyjexter.blogspot.com/2008/02/custom-hibernate-validator-that.html