12 Replies Latest reply on Feb 23, 2009 1:48 PM by goutham

    custom hibernate validators not working?

    iasdonnf32

      I'm trying to implement a new validator



      import org.hibernate.validator.ValidatorClass;
      
      @ValidatorClass(NifValidator.class)
      @Target({ElementType.METHOD,ElementType.FIELD})
      @Retention(RetentionPolicy.RUNTIME)
      @Documented
      public @interface Nif {
           boolean estricto() default true;
           String message() default "El NIF es incorrecto";
      }
      




      public class NifValidator implements Validator<Nif>,Serializable { 
           
           /**
            * 
            */
           private static final long serialVersionUID = 5098489271490642594L;
           private boolean realizarValidacionEstricta;
           
           //part of the Validator<Annotation> contract,
           //allows to get and use the annotation values
           public void initialize(Nif parameters) {
                System.out.println("inicialización de validador de NIFS");
                realizarValidacionEstricta = parameters.estricto();
           }
           
           //part of the property constraint contract
           public boolean isValid(Object value) {
                for (int i=0;i<3000000;i++)
                System.out.println("llamando a codigo de NifValidator");
                if (value==null) return false;
                if ( !(value instanceof String) ) return false;
                String string = new String((String) value);
                if(!realizarValidacionEstricta){
                     string=NifUtil.limpiarNif(string);
                }
                return NifUtil.validarNif(string);
           }
      
      }
      





      The new custom validator is applyed here:


      public class Tercero implements java.io.Serializable {
      
           private BigDecimal codTercero;
           private int version;
           private Localidads localidads;
           private Paises paises;
           private Expediente expediente;
           private Provincias provincias;
           
           @Nif
           private String cifNif;
      



      The new validator is not working. The framework doesn't call initialize nor isValid because no System.out.println. Althought when I try to use an hibernate prebuild validator it works... that is, when I replace @Nif annotation for example with @Email, then the value is validated and validation is working properly.


           //@Nif
           @Email
           private String cifNif;
      



      May I need to register the new validator in a config file? What is wrong?


      Thanks






        • 1. Re: custom hibernate validators not working?
          iasdonnf32

          Let me comment that I think it is a seam problem, I've found some others topics in this forum related with this issue, for example: http://www.seamframework.org/Community/CustomValidatorForHibernateOnlyRunsOnPersist

          • 2. Re: custom hibernate validators not working?

            Let me try to reproduce this error locally. Please provide the version information. Seam? Hibernate?

            • 3. Re: custom hibernate validators not working?
              iasdonnf32

              Hello, first, thanks you for your interest


              Seam verion is 2.0.1.GA
              hibernate version: is 3.2.6
              I'm developing with eclipse debuging with a jboss server version AS 4.2.2.GA


              We are not using JEE @Entity beans, but simples POJOS as DTO's. This classes were automaticaly generated by hibernate revenger.
              I think it may be important because all examples I've ever seen using custom validators posibly refers to use validating annotations over @Entity classes.


              The following code is the complete bean (this is the bean class with a few anotations just for testing validation, no more).


              package es.jccm.educa.app.contratacion.model.beans;
              
              // Generated 25-sep-2008 10:33:24 by Hibernate Tools 3.2.1.GA
              
              import java.math.BigDecimal;
              import java.util.Date;
              import java.util.HashSet;
              import java.util.Set;
              
              import javax.persistence.Transient;
              
              import org.hibernate.validator.AssertTrue;
              import org.hibernate.validator.Email;
              import org.hibernate.validator.NotEmpty;
              
              import es.jccm.educa.comun.Nif;
              import es.jccm.educa.comun.NifUtil;
              import es.jccm.educa.comun.PasswordPolicyRestricted;
              import es.jccm.educa.comun.UniqueSimpleKey;
              
              /**
               * Tercero generated by hbm2java
               */
              public class Tercero implements java.io.Serializable {
              
                   private BigDecimal codTercero;
                   private int version;
                   private Localidads localidads;
                   private Paises paises;
                   private Expediente expediente;
                   private Provincias provincias;
                   
                   @Nif
                   private String cifNif;
                   private String numAcreedorTarea;
                   private String tipo;
                   
                   @NotEmpty
                   private String nombre;
                   private String apellidos;
                   private String ciudad;
                   private String domicilio;
                   private String cpostal;
                   private String personaContacto;
                   private String telefono1;
                   private String telefono2;
                   private String fax1;
                   private String fax2;
                   private String movil;
                   
                   @AssertTrue(message="Msg el nif no es valido")
                   @Transient
                   public boolean isValidxyz() {
                        System.out.println(" llamando isValidxyz por el framework de validacion !!!!");
                        return false;
                   }
              
                   //@PasswordPolicyRestricted(minDigits=4)
                   //@Email
                   //@UniqueSimpleKey (tableName = "APPUSER", pkColumnName = "USER_NAME", message="This user already exists")
                   private String email;
                   
                   private String web;
                   private String activo;
                   private String usuAlta;
                   private Date FAlta;
                   private String usuModificacion;
                   private Date FModificacion;
                   private String usuBaja;
                   private Date FBaja;
                   private Set terceroEntTramitas = new HashSet(0);
                   private Set terceroContactos = new HashSet(0);
                   private Set terceroUtesForCodTercero = new HashSet(0);
                   private Set licitadors = new HashSet(0);
                   private Set expedientes = new HashSet(0);
                   private Set terceroUtesForCodUte = new HashSet(0);
                   private Set terceroTipoTerceros = new HashSet(0);
              
                   public Tercero() {
                   }
              
                   public Tercero(BigDecimal codTercero, String tipo, String nombre,
                             String activo) {
                        this.codTercero = codTercero;
                        this.tipo = tipo;
                        this.nombre = nombre;
                        this.activo = activo;
                   }
              
                   public Tercero(BigDecimal codTercero, Localidads localidads, Paises paises,
                             Expediente expediente, Provincias provincias, String cifNif,
                             String numAcreedorTarea, String tipo, String nombre,
                             String apellidos, String ciudad, String domicilio, String cpostal,
                             String personaContacto, String telefono1, String telefono2,
                             String fax1, String fax2, String movil, String email, String web,
                             String activo, String usuAlta, Date FAlta, String usuModificacion,
                             Date FModificacion, String usuBaja, Date FBaja,
                             Set terceroEntTramitas, Set terceroContactos,
                             Set terceroUtesForCodTercero, Set licitadors, Set expedientes,
                             Set terceroUtesForCodUte, Set terceroTipoTerceros) {
                        this.codTercero = codTercero;
                        this.localidads = localidads;
                        this.paises = paises;
                        this.expediente = expediente;
                        this.provincias = provincias;
                        this.cifNif = cifNif;
                        this.numAcreedorTarea = numAcreedorTarea;
                        this.tipo = tipo;
                        this.nombre = nombre;
                        this.apellidos = apellidos;
                        this.ciudad = ciudad;
                        this.domicilio = domicilio;
                        this.cpostal = cpostal;
                        this.personaContacto = personaContacto;
                        this.telefono1 = telefono1;
                        this.telefono2 = telefono2;
                        this.fax1 = fax1;
                        this.fax2 = fax2;
                        this.movil = movil;
                        this.email = email;
                        this.web = web;
                        this.activo = activo;
                        this.usuAlta = usuAlta;
                        this.FAlta = FAlta;
                        this.usuModificacion = usuModificacion;
                        this.FModificacion = FModificacion;
                        this.usuBaja = usuBaja;
                        this.FBaja = FBaja;
                        this.terceroEntTramitas = terceroEntTramitas;
                        this.terceroContactos = terceroContactos;
                        this.terceroUtesForCodTercero = terceroUtesForCodTercero;
                        this.licitadors = licitadors;
                        this.expedientes = expedientes;
                        this.terceroUtesForCodUte = terceroUtesForCodUte;
                        this.terceroTipoTerceros = terceroTipoTerceros;
                   }
              
                   public BigDecimal getCodTercero() {
                        return this.codTercero;
                   }
              
                   public void setCodTercero(BigDecimal codTercero) {
                        this.codTercero = codTercero;
                   }
              
                   public int getVersion() {
                        return this.version;
                   }
              
                   public void setVersion(int version) {
                        this.version = version;
                   }
              
                   public Localidads getLocalidads() {
                        return this.localidads;
                   }
              
                   public void setLocalidads(Localidads localidads) {
                        this.localidads = localidads;
                   }
              
                   public Paises getPaises() {
                        return this.paises;
                   }
              
                   public void setPaises(Paises paises) {
                        this.paises = paises;
                   }
              
                   public Expediente getExpediente() {
                        return this.expediente;
                   }
              
                   public void setExpediente(Expediente expediente) {
                        this.expediente = expediente;
                   }
              
                   public Provincias getProvincias() {
                        return this.provincias;
                   }
              
                   public void setProvincias(Provincias provincias) {
                        this.provincias = provincias;
                   }
                   
                   @AssertTrue(message="El nif no es valido")
                   public boolean validaCifNif(){
                        return NifUtil.validarNif(cifNif);
                   }
              
                   public String getCifNif() {
                        return this.cifNif;
                   }
              
                   
                   public void setCifNif(String cifNif) {
                        System.out.println("llamado a setNifCif");
                        this.cifNif = cifNif;
                   }
              
                   public String getNumAcreedorTarea() {
                        return this.numAcreedorTarea;
                   }
              
                   public void setNumAcreedorTarea(String numAcreedorTarea) {
                        this.numAcreedorTarea = numAcreedorTarea;
                   }
              
                   public String getTipo() {
                        return this.tipo;
                   }
              
                   public void setTipo(String tipo) {
                        this.tipo = tipo;
                   }
              
                   public String getNombre() {
                        return this.nombre;
                   }
              
                   
                   public void setNombre(String nombre) {
                        this.nombre = nombre;
                   }
              
                   public String getApellidos() {
                        return this.apellidos;
                   }
              
                   public void setApellidos(String apellidos) {
                        this.apellidos = apellidos;
                   }
              
                   public String getCiudad() {
                        return this.ciudad;
                   }
              
                   public void setCiudad(String ciudad) {
                        this.ciudad = ciudad;
                   }
              
                   public String getDomicilio() {
                        return this.domicilio;
                   }
              
                   public void setDomicilio(String domicilio) {
                        this.domicilio = domicilio;
                   }
              
                   public String getCpostal() {
                        return this.cpostal;
                   }
              
                   public void setCpostal(String cpostal) {
                        this.cpostal = cpostal;
                   }
              
                   public String getPersonaContacto() {
                        return this.personaContacto;
                   }
              
                   public void setPersonaContacto(String personaContacto) {
                        this.personaContacto = personaContacto;
                   }
              
                   public String getTelefono1() {
                        return this.telefono1;
                   }
              
                   public void setTelefono1(String telefono1) {
                        this.telefono1 = telefono1;
                   }
              
                   public String getTelefono2() {
                        return this.telefono2;
                   }
              
                   public void setTelefono2(String telefono2) {
                        this.telefono2 = telefono2;
                   }
              
                   public String getFax1() {
                        return this.fax1;
                   }
              
                   public void setFax1(String fax1) {
                        this.fax1 = fax1;
                   }
              
                   public String getFax2() {
                        return this.fax2;
                   }
              
                   public void setFax2(String fax2) {
                        this.fax2 = fax2;
                   }
              
                   public String getMovil() {
                        return this.movil;
                   }
              
                   public void setMovil(String movil) {
                        this.movil = movil;
                   }
              
                   public String getEmail() {
                        return this.email;
                   }
              
                   public void setEmail(String email) {
                        System.out.println("debug setEmail(");
                        this.email = email;
                   }
              
                   public String getWeb() {
                        return this.web;
                   }
              
                   public void setWeb(String web) {
                        this.web = web;
                   }
              
                   public String getActivo() {
                        return this.activo;
                   }
              
                   public void setActivo(String activo) {
                        this.activo = activo;
                   }
              
                   public String getUsuAlta() {
                        return this.usuAlta;
                   }
              
                   public void setUsuAlta(String usuAlta) {
                        this.usuAlta = usuAlta;
                   }
              
                   public Date getFAlta() {
                        return this.FAlta;
                   }
              
                   public void setFAlta(Date FAlta) {
                        this.FAlta = FAlta;
                   }
              
                   public String getUsuModificacion() {
                        return this.usuModificacion;
                   }
              
                   public void setUsuModificacion(String usuModificacion) {
                        this.usuModificacion = usuModificacion;
                   }
              
                   public Date getFModificacion() {
                        return this.FModificacion;
                   }
              
                   public void setFModificacion(Date FModificacion) {
                        this.FModificacion = FModificacion;
                   }
              
                   public String getUsuBaja() {
                        return this.usuBaja;
                   }
              
                   public void setUsuBaja(String usuBaja) {
                        this.usuBaja = usuBaja;
                   }
              
                   public Date getFBaja() {
                        return this.FBaja;
                   }
              
                   public void setFBaja(Date FBaja) {
                        this.FBaja = FBaja;
                   }
              
                   public Set getTerceroEntTramitas() {
                        return this.terceroEntTramitas;
                   }
              
                   public void setTerceroEntTramitas(Set terceroEntTramitas) {
                        this.terceroEntTramitas = terceroEntTramitas;
                   }
              
                   public Set getTerceroContactos() {
                        return this.terceroContactos;
                   }
              
                   public void setTerceroContactos(Set terceroContactos) {
                        this.terceroContactos = terceroContactos;
                   }
              
                   public Set getTerceroUtesForCodTercero() {
                        return this.terceroUtesForCodTercero;
                   }
              
                   public void setTerceroUtesForCodTercero(Set terceroUtesForCodTercero) {
                        this.terceroUtesForCodTercero = terceroUtesForCodTercero;
                   }
              
                   public Set getLicitadors() {
                        return this.licitadors;
                   }
              
                   public void setLicitadors(Set licitadors) {
                        this.licitadors = licitadors;
                   }
              
                   public Set getExpedientes() {
                        return this.expedientes;
                   }
              
                   public void setExpedientes(Set expedientes) {
                        this.expedientes = expedientes;
                   }
              
                   public Set getTerceroUtesForCodUte() {
                        return this.terceroUtesForCodUte;
                   }
              
                   public void setTerceroUtesForCodUte(Set terceroUtesForCodUte) {
                        this.terceroUtesForCodUte = terceroUtesForCodUte;
                   }
              
                   public Set getTerceroTipoTerceros() {
                        return this.terceroTipoTerceros;
                   }
              
                   public void setTerceroTipoTerceros(Set terceroTipoTerceros) {
                        this.terceroTipoTerceros = terceroTipoTerceros;
                   }
              
              }
              









              • 4. Re: custom hibernate validators not working?
                iasdonnf32

                I forgot comment also that framework doesn't executes this validating function:



                @AssertTrue(message="Msg el nif no es valido")
                     @Transient
                     public boolean isValidxyz() {
                          System.out.println(" llamando isValidxyz por el framework de validacion !!!!");
                          return false;
                     }
                



                • 5. Re: custom hibernate validators not working?

                  You can use hibernate validator on regular POJOs.
                  I think the problem here is error message is not displayed if your jsf control is not wrapped with s:decorate.


                  This displays error message.


                  <s:decorate id="customInputField" template="layout/edit.xhtml">
                     <h:inputText id="customInput" value="#{myPojo.myProperty}" />
                  </s:decorate> 



                  This does not.


                  <s:validateAll>            
                    <h:inputText id="indicationF"
                                             size="10"
                                        maxlength="10"
                                            value="#{seampojo.testValidation}" />
                    <s:message />
                  </s:validateAll>



                  This might be a bug. Please look in jira.


                  I used the following combination
                  Seam 2.1.1.GA and Hibernate-validator 3.1.0.CR2

                  • 6. Re: custom hibernate validators not working?
                    goutham

                    Binesh Gummadi wrote on Feb 17, 2009 19:33:


                    You can use hibernate validator on regular POJOs.
                    I think the problem here is error message is not displayed if your jsf control is not wrapped with s:decorate.

                    This displays error message.

                    <s:decorate id="customInputField" template="layout/edit.xhtml">
                       <h:inputText id="customInput" value="#{myPojo.myProperty}" />
                    </s:decorate> 



                    This does not.

                    <s:validateAll>            
                      <h:inputText id="indicationF"
                                               size="10"
                                          maxlength="10"
                                              value="#{seampojo.testValidation}" />
                      <s:message />
                    </s:validateAll>



                    This might be a bug. Please look in jira.

                    I used the following combination
                    Seam 2.1.1.GA and Hibernate-validator 3.1.0.CR2



                    Hello Guys,


                    I'm not sure if this is a bug or not , but I did get a similar problem.


                    The catch here is that I'm using Icefaces instead of Jsf or seam tags.


                    The code runs fine with normal hibernate tags such as @Email, @Length etc, but when I annotate my own custom validator , the code bombs with a null pointer exception!!..


                    Please can anyone help!. My code is similar to the one posted above, but if you need the icefaces integration part please do let me know and I will post the same.


                    Cheers,
                    Goutham


                    Click HELP for text formatting instructions. Then edit this text and check the preview.

                    • 7. Re: custom hibernate validators not working?
                      jguglielmin

                      With ICEfaces, there are various ways you can implement the validators (custom or otherwise).  You would have to post code/markup for detailed assistance.  Please check the following ICEfaces forum posting in case this helps you. (you could also post code there for further assistance)

                      • 8. Re: custom hibernate validators not working?
                        goutham

                        Hello Judy,

                        I have seen the above link that you showed me and that is where i got the idea of writing my own validator.
                        I have put down the code below , please can you let me know what is that i'm doing wrong here?

                        public @interface UniqueUser {
                        
                                Unique type() default Unique.FIRSTNAME;
                                String message() default "The input is unique";
                                Unique value();
                                
                        
                        
                        }
                        


                        public class UniqueUserName implements Validator<UniqueUser>, PropertyConstraint {
                        
                                private Unique type; 
                                private String uniquenessCheckValue;
                                
                                @In
                                  EntityManager entityManager;
                                
                                public void initialize(UniqueUser parameters) 
                                {
                                
                                        type = parameters.type();
                                        
                                }
                        
                                public boolean isValid(Object value ) {
                                        
                                        if( value == null ) return false;
                                        
                                        if( type == Unique.FIRSTNAME )
                                        {
                                                uniquenessCheckValue=(String)value;
                                                
                                                Query q = entityManager.createQuery("SELECT u FROM User u " +
                                                "WHERE u.username = '?'").setParameter(1, uniquenessCheckValue);
                                                
                                                try {
                                        
                                                        User  user = (User) q.getSingleResult();
                                            return true;
                                          } catch (NoResultException nre) {
                                            return false;
                                          }
                                        }
                                                
                                        return false;
                                }
                        
                                public void apply(Property arg0) {
                                        
                                        
                                }
                        




                        And the icefaces code that is fired from


                             <ice:inputText id="userId" value="#{user.username}" partialSubmit="true" validator="#{registerUser.validateUserName}"></ice:inputText>




                        And the backing bean code where the validation that happens

                        @Scope(ScopeType.EVENT)
                        @Name("registerUser")
                        public class UserCrud {
                        
                        public void validateUserName( FacesContext context, UIComponent validate, Object value)
                        {
                        
                              org.jboss.seam.ui.validator.ModelValidator mv = new ModelValidator();
                              mv.validate(context,validate, value);
                              context.addMessage(validate.getClientId(context), msg);
                                HtmlInputText inputText = (HtmlInputText)validate;
                                inputText.setFocus(true);
                        
                        }
                        }
                        



                        Java bean code where this is applied to

                        @Entity
                        @Name("user")
                        @Scope(SESSION)
                        @Table(name = "Customer")
                        public class User implements Serializable {
                        
                             private String username;
                             private String password;
                             private String name;
                        
                             public User(String username, String password, String name) {
                                  super();
                                  this.username = username;
                                  this.password = password;
                                  this.name = name;
                             }
                        
                             public User() {
                             }
                        
                             @NotNull
                             @Length(max = 100)
                             public String getName() {
                                  return name;
                             }
                        
                             public void setName(String name) {
                                  this.name = name;
                             }
                        
                             @NotNull
                             @Length(min = 3, max = 10)
                             public String getPassword() {
                                  return password;
                             }
                        
                             public void setPassword(String password) {
                                  this.password = password;
                             }
                        
                             @Id
                             @Length(min = 3, max = 15)
                             @Pattern(regex = "^\\w*$", message = "not a valid username")
                             public String getUsername() {
                                  return username;
                             }
                        
                        



                        Now if annotate the username field with @Unique i'm getting a null pointer exception , else the rest of the validation seems to happen fine .
                        • 9. Re: custom hibernate validators not working?
                          jguglielmin

                          I think you're going to have to trace this one through the debugger.  I don't put a scope or a @Name on my Entity beans...instead manage the instances of them instead in other classes.  Also, having validator equals on an  ice input component means you don't have to implement  Validator.  But maybe you need this design for some reason...so I would watch the phases and watch the values as well as how many jsf lifecycles you are getting from the partial submit.

                          • 10. Re: custom hibernate validators not working?
                            goutham

                            judy guglielmin wrote on Feb 20, 2009 18:06:


                            I think you're going to have to trace this one through the debugger.  I don't put a scope or a @Name on my Entity beans...instead manage the instances of them instead in other classes.  Also, having validator equals on an  ice input component means you don't have to implement  Validator.  But maybe you need this design for some reason...so I would watch the phases and watch the values as well as how many jsf lifecycles you are getting from the partial submit.




                            Thanks Judy. How do I attach a debugger. At the moment I am packaging the projects into a war using maven and copying the war files to tomcat deployment directory. Is there a resource i can look into? Thanks Again.
                            • 11. Re: custom hibernate validators not working?
                              goutham

                              Goutham Rao wrote on Feb 23, 2009 12:01:



                              judy guglielmin wrote on Feb 20, 2009 18:06:


                              I think you're going to have to trace this one through the debugger.  I don't put a scope or a @Name on my Entity beans...instead manage the instances of them instead in other classes.  Also, having validator equals on an  ice input component means you don't have to implement  Validator.  But maybe you need this design for some reason...so I would watch the phases and watch the values as well as how many jsf lifecycles you are getting from the partial submit.



                              Thanks Judy. How do I attach a debugger. At the moment I am packaging the projects into a war using maven and copying the war files to tomcat deployment directory. Is there a resource i can look into? Thanks Again.



                              Soory, What i mean is I can get the eclipse debugger to step through my code , but i get an exception at  mv.validate(context,validate, value);. The reason it is getting null is because my annotaion is not being recognised. I need to know how SEAM annotates the fields, i am just not able to figure out what is happening inside the seam environment

                              Click HELP for text formatting instructions. Then edit this text and check the preview.

                              • 12. Re: custom hibernate validators not working?
                                goutham

                                Hi Its solved now. The reason i was getting the null pointer exception was because the entity manager was not getting injected. I solved it by using
                                EntityManager entityManager= (EntityManager) Component.getInstance("entityManager"); 



                                and then running my queries. Thanks for your help again