Use-site with delegated properties

Hi,

Consider the following delegate that handles a String property. Delegation is used to trim the String value before setting it.

class TrimmedStringProperty(var value: String?) {

    operator fun getValue(thisRef: Any?, property: KProperty<*>): String? = value

    operator fun setValue(thisRef: Any?, property: KProperty<*>, v: String?) {
        value = v?.trim()
    }

}

Here is a class using the above:

import org.hibernate.validator.constraints.NotBlank
import javax.validation.constraints.Size

class Jsr303Bean {

    @delegate:NotBlank
    @delegate:Size(max = 12)
    var something: String? by TrimmedStringProperty(null)

}

I’m trying to validate the delegated property following JSR 303. On doing this I observed the following error:

javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint 'javax.validation.constraints.Size' validating type 'TrimmedStringProperty'. Check configuration for 'description$delegate'
                at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.throwExceptionForNullValidator(ConstraintTree.java:229)
                at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.getConstraintValidatorNoUnwrapping(ConstraintTree.java:310)
                at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.getConstraintValidatorInstanceForAutomaticUnwrapping(ConstraintTree.java:244)

What am I missing here? I understand that the use-site mechanism is used to attach annotations to fields/getter/setter etc. (How) does it work in conjunction with delegates?

Thanks,
Manoj

If, from what I understand, those validations are supposed to be applied when the value is set, right? If so, then do @set:NotBlank . This is because while you are using a delegate to set the value, the property still does have its own setSomething function that calls the delegate inside, and so by doing this you’ll do the validation checks before the value even reaches the delegate. @delegate: basically applies the annotation on the actual delegate field itself i.e. the filed that’s holding the value of the delegate object.

The validation is usually applied after setting the values. An instance of is Jsr303Bean created, populated, and then validated. Without delegation I’d have used @field:Size, @field:NotBlank etc.

1 Like

Could you outline the syntax for this? Will it precede/succeed @delegate:?

1 Like

I meant as in like are the validations supposed to be applied to the setter? From what I’m gathering, they are supposed to be. So, the code will look something like this:

class Jsr303Bean {
    @set:NotBlank
    @set:Size(max = 12)
    var something: String? by TrimmedStringProperty(null)
}

which should hopefully accomplish what you need.