5 Replies Latest reply on Feb 16, 2009 11:19 PM by Binesh Gummadi

    Custom Validator for Hibernate only runs on persist

    Steffen Persch Newbie

      Hi together,

      first I want to introduce myself. I am Steffen Persch from Germany, I'm 22years old and I have been java coder for now 2,5 years and seam coder for 1year.

      I was searching for a solution for my problem but I did not find anyone. I have written a custom Validator for Hibernate (code below) and it works, but only when I called my entityManager with a persist. What have I to do now that it will work with <s:validateAll> ?

      Sry for my non perfect English, I hope you understand me.

      Here my classes:

      package de.dssc.validator;
      import java.lang.annotation.Documented;
      import java.lang.annotation.Retention;
      import java.lang.annotation.Target;
      import static java.lang.annotation.ElementType.*;
      import static java.lang.annotation.RetentionPolicy.*;
      import org.hibernate.validator.ValidatorClass;
      @Target({FIELD, METHOD})
      public @interface ImageValidator {
        /** @return error message key */
        String message() default "{validator.imageValidator}";

      package de.dssc.validator;
      import java.util.*;
      import org.hibernate.validator.*;
      public class DSSCImageValidator implements
          Validator<ImageValidator> {
          private static final Set<byte[]> VALID_HEX_BYTES = new HashSet<byte[]>();
          static {
              byte[] jpeg = {(byte) 0xFF, (byte) 0xD8, (byte) 0xFF, (byte) 0xE0};
              byte[] jpegExif = {(byte) 0xFF, (byte) 0xD8, (byte) 0xFF, (byte) 0xE1};
              byte[] jpegQM = {(byte) 0x4A, (byte) 0x46, (byte) 0x49, (byte) 0x46};
          public boolean isAllowedType(byte[] firstBytes) {
              for (byte[] byteArr : VALID_HEX_BYTES) {
                  if (Arrays.equals(byteArr, firstBytes)) {
                      return true;
              return false;
          public void initialize(ImageValidator arg0) {
              // TODO Auto-generated method stub
          public boolean isValid(Object obj) {
              System.out.println("DSSC IMAGE VALIDATOR: Validator called!");
              final byte[] imageData = (byte[]) obj;
              final byte[] firstBytes = Arrays.copyOfRange(imageData, 0, 4);
              if(!isAllowedType(firstBytes)) {
                  return false;
              return true;

      And my field in the entity:

      @Column(columnDefinition = "MEDIUMBLOB")
      @ImageValidator(message = "pic error message")
      private byte[] picture;

      Best regards

        • 1. Re: Custom Validator for Hibernate only runs on persist
          Binesh Gummadi Novice

          If I understood it right, you want to have ajax validation in your xhtml so it would immediately show the error message?

          Show us your xhtml file.

          • 2. Re: Custom Validator for Hibernate only runs on persist
            Steffen Persch Newbie

            No, ajax validation is not the problem. Normally when I click the next-button and any field is invalid I get an error in the facesMessages (<h:messages />) but not at this field, so I get only an validationFailed exception in the console. If the input is correct, all works fine.

            Here is my xhtml file, reduced to the important things and the method i call up by #{registration.register}:

            <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
            <ui:composition xmlns="http://www.w3.org/1999/xhtml"
                <ui:define name="content">
                    <s:div layout="block" styleClass="conwrapper">
                        <h:messages styleClass="errorList" />
                        <form jsfc="h:form" enctype="multipart/form-data">
                            <fieldset class="personalData">
                                <legend>Persönliche Informationen</legend>
                                <label for="picture" jsfc="h:outputLabel">Benutzerbild:</label>
                                <s:fileUpload id="picture" data="#{driver.picture}" accept="image/*" required="true" requiredMessage="Benutzerbild erforderlich" />
                            <input type="submit" value="Anmeldung abschliesen" action="#{registration.register}" jsfc="h:commandButton" styleClass="finreg" />

            public String register() {
                    if (null != oldDriver) {
                    if (null == driver.getDriverNo()) {
                        final ComputeRangeNo computeDN = new ComputeRangeNo(driverType, em);
                        final Integer newDriverNo = computeDN.compute();
                        log.info("Generated new DriverNo: " + newDriverNo);
                    final PwdGenerator pwdGenerator = new PwdGenerator();
                    final EncryptService es = new EncryptService(pwdGenerator.getPassword(8));
                    this.newPassword = es.generatePasswordString("MD5");
                    log.info("Fahrer " + driver.getFirstName() + " " + driver.getLastName() + " gespeichert. (" + driver.getId() + ")");
                    return "/regged";

            • 3. Re: Custom Validator for Hibernate only runs on persist
              Binesh Gummadi Novice

              I looked at your code carefully and thats exactly how it should be. try to use h:messages with globalonly set to true and see if it is displaying the error message.

              • 4. Re: Custom Validator for Hibernate only runs on persist
                Steffen Persch Newbie

                I dont think that the <h:messages /> is the problem. My validator class is only called up on the persist, not before. Do I have to register my validator on any settings file that it is called up of the event type pre-persist / pre-validate?

                • 5. Re: Custom Validator for Hibernate only runs on persist
                  Binesh Gummadi Novice

                  You don't have to register.

                  I fire onblur event and validation happens right away. At some point I had to implement Serializable to make it work but don't really remember why and what version of hibernate and seam.