Tonny Tc
Tonny Tc

Reputation: 930

Throw javax.validation.UnexpectedTypeException: HV000030 exception when validating Scala's Map with @NotEmpty

When I tried to validate a Scala's Map, no matter mutable or immutable, I got an exception like:

javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint 'javax.validation.constraints.Size' validating type 'scala.collection.mutable.Map<java.lang.String, java.lang.String>'. Check configuration for 'corporationSecrets'
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.throwExceptionForNullValidator(ConstraintTree.java:229) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.getConstraintValidatorNoUnwrapping(ConstraintTree.java:310) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.getConstraintValidatorInstanceForAutomaticUnwrapping(ConstraintTree.java:244) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.getInitializedConstraintValidator(ConstraintTree.java:163) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:116) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateComposingConstraints(ConstraintTree.java:398) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:98) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:87) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
    at org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:73) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateMetaConstraint(ValidatorImpl.java:621) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:584) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForSingleDefaultGroupElement(ValidatorImpl.java:528) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:496) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:461) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:411) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
    at org.hibernate.validator.internal.engine.ValidatorImpl.validate(ValidatorImpl.java:208) ~[hibernate-validator-5.3.6.Final.jar:5.3.6.Final]
    at org.springframework.validation.beanvalidation.SpringValidatorAdapter.validate(SpringValidatorAdapter.java:102) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.validation.DataBinder.validate(DataBinder.java:877) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.boot.bind.PropertiesConfigurationFactory.doBindPropertiesToTarget(PropertiesConfigurationFactory.java:274) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
    at org.springframework.boot.bind.PropertiesConfigurationFactory.bindPropertiesToTarget(PropertiesConfigurationFactory.java:240) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
    at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization(ConfigurationPropertiesBindingPostProcessor.java:330) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
    ... 29 common frames omitted

My code is very simple, like

@NotEmpty
val corporationSecrets : scala.collection.mutable.Map[String, String] = new scala.collection.mutable.HashMap[String, String]

How can I validate a scala's map to check whether it is empty or not?

Upvotes: 0

Views: 1093

Answers (2)

Guillaume Smet
Guillaume Smet

Reputation: 10529

So what you have to understand is that in Hibernate Validator, for a given constraint, you register constraint validators for different types.

Typically, for the @Size constraint, we will register constraint validators for String, Collection, Map, arrays...

The issue you have here is that the Scala types don't implement the classical Java interfaces so we can't find a constraint validator for them. That's why you get your exception: HV recognizes the constraint but can't find a constraint validator to apply it on your Scala Map.

As far as I can see from the code, https://github.com/bean-validation-scala/bean-validation-scala would be the way to go to get BV and HV support for Scala. It delegates the validation to the original HV implementations so you should have a very similar behavior to what is done with Java.

I don't think it's outdated as keep in mind that the BV/HV project didn't change too much for a while, before we started the work on BV 2.0 and HV 6.0. It might be a good idea to ping the original author regarding the BV 2.0 and HV 6.0 support (we have new constraints and so on).

Upvotes: 1

Alex Cuadr&#243;n
Alex Cuadr&#243;n

Reputation: 688

If you want to check if a map collection is empty or not you could do this: if(mapVariable.isEmpty() || mapVariable == null){...}

Or write traversable shouldBe empty or javaMap should not be empty as stated in the second link (link to the API). Check out this or this for further information.

EDIT

Try to add @Valid to the collection.

Here is an example from the Hibernate Validator Reference.

public class Car { 
@NotNull 
@Valid 
private List<Person> passengers = new ArrayList<Person>(); 
}

This is standard JSR-303 behavior. See Section 3.1.3 of the spec.

Upvotes: 0

Related Questions