0
votes

i'm developing a portlet on liferay 6.2 using spring mvc + jpa 2.1 + hibernate validator

in my pom i have

....
 <dependency> 
            <groupId>org.hibernate</groupId> 
            <artifactId>hibernate-entitymanager</artifactId> 
            <version>5.0.6.Final</version> 
        </dependency>   
        <dependency>
            <groupId>javax.transaction</groupId>
            <artifactId>jta</artifactId>
            <version>1.1</version>
        </dependency>        
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-c3p0</artifactId>
            <version>5.0.6.Final</version> 
        </dependency>                
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.1-api</artifactId>
            <version>1.0.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.2.2.Final</version>
        </dependency>        
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator-annotation-processor</artifactId>
            <version>5.2.2.Final</version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-log4j12</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>  
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
        </dependency>              
....

i created some custom constraint for hibernate validator

@Target({FIELD, METHOD})
@Retention(RUNTIME)
@Constraint(validatedBy = CheckCodiceFiscaleValidator.class)
@Documented
public @interface CheckCF {
    String message() default "{validator.assertFalse}";

    Class<? extends Payload>[] payload() default { };

    Class<?>[] groups() default { };
}

and the implemented validator is

public class CheckCodiceFiscaleValidator implements ConstraintValidator<CheckCF, String> {

    @Override
    public void initialize(CheckCF constraintAnnotation) {
        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public boolean isValid(String object, ConstraintValidatorContext constraintContext) {
        //constraintContext.disableDefaultConstraintViolation();
        constraintContext.buildConstraintViolationWithTemplate(
                "{it.realt.validator.constraint.custom.cf.genericError.message}").addConstraintViolation();
        if (Strings.isNullOrEmpty(object)) {
            return false;
        }

        return validaCF(object, constraintContext);
    }

    private boolean validaCF(String cf, ConstraintValidatorContext constraintContext) {
        int i, s, c;
        String cf2;
        int setdisp[]
                = {
                    1, 0, 5, 7, 9, 13, 15, 17, 19, 21, 2, 4, 18, 20,
                    11, 3, 6, 8, 12, 14, 16, 10, 22, 25, 24, 23
                };
        if (cf.length() == 0) {
            constraintContext.buildConstraintViolationWithTemplate(
                    "{it.realt.validator.constraint.custom.cf.notEmpty.message}").addConstraintViolation();
            return false;
        }
        if (cf.length() != 16) {
            constraintContext.buildConstraintViolationWithTemplate(
                    "{it.realt.validator.constraint.custom.cf.tooShort.message}").addConstraintViolation();
            return false;
        }
        cf2 = cf.toUpperCase();
        for (i = 0; i < 16; i++) {
            c = cf2.charAt(i);
            if (!(c >= '0' && c <= '9' || c >= 'A' && c <= 'Z')) {
                constraintContext.buildConstraintViolationWithTemplate(
                        "{it.realt.validator.constraint.custom.cf.invalidChars.message}").addConstraintViolation();
                return false;
            }
        }
        s = 0;
        for (i = 1; i <= 13; i += 2) {
            c = cf2.charAt(i);
            if (c >= '0' && c <= '9') {
                s = s + c - '0';
            } else {
                s = s + c - 'A';
            }
        }
        for (i = 0; i <= 14; i += 2) {
            c = cf2.charAt(i);
            if (c >= '0' && c <= '9') {
                c = c - '0' + 'A';
            }
            s = s + setdisp[c - 'A'];
        }
        if (s % 26 + 'A' != cf2.charAt(15)) {
            constraintContext.buildConstraintViolationWithTemplate(
                    "{it.realt.validator.constraint.custom.cf.controlCode.message}").addConstraintViolation();
            return false;
        }
        return true;
    }
}

in the entity class i have

...
    @Column(name = "cognome")
    @NotEmpty
    private String cognome;

    @Column(name = "nome")
    @NotEmpty
    private String nome;

    @Column(name = "indirizzo")
    @NotEmpty
    private String indirizzo;

    @Column(name = "cap")
    @NotEmpty
    @Length(min=5, max=5)
    private String cap;

    @Column(name = "citta")
    @NotEmpty
    private String citta;

    @Column(name = "provincia")
    @NotEmpty
    private String provincia;

    @Column(name = "partita_iva")
    @CheckPIVA
    private String partitaIva;

    @Column(name = "codice_fiscale")
    @CheckCF
    private String codiceFiscale;
...

in my controller i put @Valid annotation

...
@ActionMapping(params = "action=register")
public void richiestaRegistrazione(ActionRequest actionRequest, ActionResponse actionResponse, 
        @ModelAttribute("anagrafica") @Valid Anagrafica anagrafica, BindingResult result, Model model) throws IOException,
                 PortletException {
        boolean succeded = this.anagraficaManager.richiediRegistrazione(anagrafica);
        model.addAttribute("succeded", succeded);
}
...

and finally the jsp is

    ...
    <form:form name="<portlet:namespace/>anagrafica" modelAttribute="anagrafica" action="${registraRichiestaURL}" method="post">
<center>
    <table>

        <tr align="left">
            <th align="right">Partita IVA: </th>
            <td align="left" class="generale"><span><form:input path="partitaIva" maxlength="11"/><form:errors path="partitaIva" cssClass="error"/></span></td>
        </tr>
    ...

when i submit the form the validation fails and i get the exception

javax.validation.ConstraintViolationException: Validation failed for classes [it.realt.mypos.domain.Anagrafica] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
    ConstraintViolationImpl{interpolatedMessage='may not be empty', propertyPath=cap, rootBeanClass=class it.realt.mypos.domain.Anagrafica, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'}
    ConstraintViolationImpl{interpolatedMessage='may not be empty', propertyPath=natoA, rootBeanClass=class it.realt.mypos.domain.Anagrafica, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'}
    ConstraintViolationImpl{interpolatedMessage='may not be empty', propertyPath=citta, rootBeanClass=class it.realt.mypos.domain.Anagrafica, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'}
    ConstraintViolationImpl{interpolatedMessage='may not be empty', propertyPath=provincia, rootBeanClass=class it.realt.mypos.domain.Anagrafica, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'}
    ConstraintViolationImpl{interpolatedMessage='may not be empty', propertyPath=indirizzo, rootBeanClass=class it.realt.mypos.domain.Anagrafica, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'}
    ConstraintViolationImpl{interpolatedMessage='may not be empty', propertyPath=cognome, rootBeanClass=class it.realt.mypos.domain.Anagrafica, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'}
    ConstraintViolationImpl{interpolatedMessage='may not be empty', propertyPath=nome, rootBeanClass=class it.realt.mypos.domain.Anagrafica, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'}
    ConstraintViolationImpl{interpolatedMessage='may not be null', propertyPath=natoIl, rootBeanClass=class it.realt.mypos.domain.Anagrafica, messageTemplate='{javax.validation.constraints.NotNull.message}'}
    ConstraintViolationImpl{interpolatedMessage='Si è verificato un errore nel controllo del Codice Fiscale', propertyPath=codiceFiscale, rootBeanClass=class it.realt.mypos.domain.Anagrafica, messageTemplate='{it.realt.validator.constraint.custom.cf.genericError.message}'}
    ConstraintViolationImpl{interpolatedMessage='{validator.assertFalse}', propertyPath=codiceFiscale, rootBeanClass=class it.realt.mypos.domain.Anagrafica, messageTemplate='{validator.assertFalse}'}
    ConstraintViolationImpl{interpolatedMessage='length must be between 5 and 5', propertyPath=cap, rootBeanClass=class it.realt.mypos.domain.Anagrafica, messageTemplate='{org.hibernate.validator.constraints.Length.message}'}
]
    at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:138)
    at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:78)
    at org.hibernate.action.internal.EntityInsertAction.preInsert(EntityInsertAction.java:205)
    at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:82)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:560)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:434)
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39).....

and no errors are binded in the page...

I checked with several examples found in google and it seems i made all correct...so, where is the problem?

Thanks

andrea

1

1 Answers

0
votes

Your example is correct, why no errors are binded in your page for the simple reason, you have any error in your field "partitaIva" as you can see in the ConstraintViolationException trace.

if you want to show all errors you must remove the path attribute from

<form:errors path="partitaIva" cssClass="error"/>