Search code examples
spring-mvcspring-bootbean-validationhibernate-validator

Bean validation : Duplicate annotation Exception


I have defined this constraint :

@Size( min = 5 )
@NotBlank
@Pattern.List( {
        @Pattern( regexp = "(?=.*[0-9]).+", message = "au moins un chiffre" ),
        @Pattern( regexp = "(?=.*[a-z]).+", message = "au moins une lettre miniscule" ),
        @Pattern( regexp = "(?=.*[A-Z]).+", message = "au moins une lettre majiscule" ),
        @Pattern( regexp = "(?=.*[!@#$%^&*+=?-_()/\"\\.,<>~`;:]).+", message = "au moins un caractère spécial" ),
        @Pattern( regexp = "(?=\\S+$).+", message = "pas d'espace" )
} )
private String    password;

But when I send invalid password which not respect this constraint, I have the exception bellow :

java.lang.annotation.AnnotationFormatError: Duplicate annotation for class: interface javax.validation.constraints.Pattern: @javax.validation.constraints.Pattern(flags=[], groups=[], message=au moins une lettre miniscule, payload=[], regexp=(?=.*[a-z]).+)
    at sun.reflect.annotation.TypeAnnotationParser.mapTypeAnnotations(Unknown Source) ~[na:1.8.0_162]
    at sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedTypeBaseImpl.<init>(Unknown Source) ~[na:1.8.0_162]
    at sun.reflect.annotation.AnnotatedTypeFactory.buildAnnotatedType(Unknown Source) ~[na:1.8.0_162]
    at sun.reflect.annotation.TypeAnnotationParser.buildAnnotatedType(Unknown Source) ~[na:1.8.0_162]
    at java.lang.reflect.Field.getAnnotatedType(Unknown Source) ~[na:1.8.0_162]
    at org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider.findCascadingMetaData(AnnotationMetaDataProvider.java:614) ~[hibernate-validator-6.0.7.Final.jar:6.0.7.Final]
    at org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider.findPropertyMetaData(AnnotationMetaDataProvider.java:236) ~[hibernate-validator-6.0.7.Final.jar:6.0.7.Final]
    at org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider.getFieldMetaData(AnnotationMetaDataProvider.java:225) ~[hibernate-validator-6.0.7.Final.jar:6.0.7.Final]
    at org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider.retrieveBeanConfiguration(AnnotationMetaDataProvider.java:133) ~[hibernate-validator-6.0.7.Final.jar:6.0.7.Final]
    at org.hibernate.validator.internal.metadata.provider.AnnotationMetaDataProvider.getBeanConfiguration(AnnotationMetaDataProvider.java:124) ~[hibernate-validator-6.0.7.Final.jar:6.0.7.Final]
    at org.hibernate.validator.internal.metadata.BeanMetaDataManager.getBeanConfigurationForHierarchy(BeanMetaDataManager.java:220) ~[hibernate-validator-6.0.7.Final.jar:6.0.7.Final]
    at org.hibernate.validator.internal.metadata.BeanMetaDataManager.createBeanMetaData(BeanMetaDataManager.java:187) ~[hibernate-validator-6.0.7.Final.jar:6.0.7.Final]
    at org.hibernate.validator.internal.metadata.BeanMetaDataManager.lambda$getBeanMetaData$0(BeanMetaDataManager.java:160) ~[hibernate-validator-6.0.7.Final.jar:6.0.7.Final]
    at java.util.concurrent.ConcurrentMap.computeIfAbsent(Unknown Source) ~[na:1.8.0_162]

What is going wrong?


Solution

  • Hum. So this is an Eclipse compiler bug (you might encounter it with another IDE using the Eclipse compiler).

    Compiling with javac (e.g. if you do a mvn clean install) works without any issue.

    The only workaround you have is to upgrade to Hibernate Validator 6+ where all the constraint annotations are marked as repeatable.

    You can then do:

    @Size( min = 5 )
    @NotBlank
    @Pattern( regexp = "(?=.*[0-9]).+", message = "au moins un chiffre" ),
    @Pattern( regexp = "(?=.*[a-z]).+", message = "au moins une lettre miniscule" ),
    @Pattern( regexp = "(?=.*[A-Z]).+", message = "au moins une lettre majiscule" ),
    @Pattern( regexp = "(?=.*[!@#$%^&*+=?-_()/\"\\.,<>~`;:]).+", message = "au moins un caractère spécial" ),
    @Pattern( regexp = "(?=\\S+$).+", message = "pas d'espace" )
    private String    password;
    

    without the List construct.

    And in this case, the compiler works as expected (at least with Oxygen.3).

    I'll open a bug at Eclipse, see if they can do something about it.

    Update: the Eclipse issue: https://bugs.eclipse.org/bugs/show_bug.cgi?id=533199