I have create a validation annotation to validate the content of a string. The definition of my annotation looks like this:
#NotNull
#Size(min = 2, max = 128, groups = First.class)
#Pattern(regexp = "^(?!WP_([0-9])+$)[A-Z_][A-Z0-9_-]+", groups = Second.class)
#Target({FIELD, ANNOTATION_TYPE})
#Retention(RUNTIME)
#Documented
#Constraint(validatedBy = {})
#GroupSequence(value={First.class, Second.class})
public #interface ValidIntentName {
String message() default "";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
My problem is that i cannot order the #Size and #Pattern execution. I've tried a couple of things but no luck so far.
Basically I need #Size to be executed before #Pattern
First and Second interfaces are defined. There are no errors during compilation is just that during run-time #Patter is executed before #Size.
Any idea what I'm doing wrong?
I'm running Java 8.
Thanks
Related
I'm wondering if it's possible to do something like:
#Min(1)
#Max(100)
public #interface ValidationForX {}
and then
#ValidationForX
int X;
For some reason #Min and #Max are applicable on annotations so I'm assuming it should be possible
I want to hide this validation behind one annotation because I want to reuse it
Thanks for your help!
You annotation must look like this:
#Min(1)
#Max(100)
#Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
#Retention(RUNTIME)
#Documented
#Constraint(validatedBy = {})
public #interface ValidationForX {
String message() default "value should be greater or equal than 1 and less or equal than 100.";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Read more about composing constraints here: https://www.baeldung.com/java-bean-validation-constraint-composition
You can directly use #Min and #Max annotation on top of the field which you want to validate.
Something like this:
#Max(value=100)
#Min(value=1)
int X;
I have a working custom class level constraint that validates all annotations that do not belong in a group. How can I change that to validate a specific group with that constraint?
This is the annotation class I have:
#Target({TYPE, ANNOTATION_TYPE})
#Retention(RUNTIME)
#Constraint(validatedBy = CheckCase.class)
#Documented
public #interface ValidName {
String message() default "{message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
#Target({TYPE, ANNOTATION_TYPE})
#Retention(RUNTIME)
#Documented
#interface List {
ValidName[] value();
}
}
Right now, the validation works only if I use:
#CheckCase(message = "Error message")
I would like to use this:
#CheckCase(message = "Error message", groups = CheckCaseGroup.class)
Do I have to change something in the following line?
Class<?>[] groups() default {};
Separate question:
If I run the validator without passing in a group, will it go through all validations including the ones that have a group, or will it go only through the ones that don't have a specified group? For example:
will running this:
validator.validate(inputData);
go through this annotations:
#NotBlank(groups = CheckCaseGroup.class)
or only this:
#NotBlank()
So I have created a custom constraint validator annotation like so:
#Documented
#Constraint(validatedBy = PostcodeValidator.class)
#Target( { ElementType.METHOD, ElementType.FIELD })
#Retention(RetentionPolicy.RUNTIME)
public #interface Postcode {
String message() default "not a well-formed postcode";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
and I wanted to use it in combination with others like so:
#NotEmpty
#Postcode
private final String postcode;
But when attempting to test this I get the following:
java.lang.IllegalStateException: Duplicate key not a well-formed postcode
I was expecting it to fail the #NotEmpty constraint.
I know I can use composition to include one constraint within the other, but my question is, is it possible to use them as I am? And if so, what am I doing wrong?
Cheers,
I want to build a NotNull check that only work on Create group, so I can write like this
#Data
public static class TestDto {
#NotNullOnCreate
// #NotNull(groups = Create.class) // instead of this
private String id;
}
I create the NotNullOnCreate like this
#Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
#Retention(RUNTIME)
#Documented
#Repeatable(NotNullOnCreate.List.class)
#ReportAsSingleViolation
#Constraint(validatedBy = {})
#NotNull(groups = Create.class)
#interface NotNullOnCreate {
String message() default "{javax.validation.constraints.NotNull.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
#Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
#Retention(RUNTIME)
#Documented
#interface List {
NotNullOnCreate[] value();
}
}
This doesn't work, because composing constraint annotation's (see ConstraintDescriptorImpl#createComposingConstraintDescriptor) group will be set to host annotation's group('Default').
I also tried this Class<?>[] groups() default {Create.class};, but this is not allowed, the default group must empty.
How can I achieve this ? I don't want to write the group everywhere.
EDIT
Create HV-1355 Constraint annotation with explicit groups
Wrote a workable demo project hv-annotation-with-group
This is not possible at the moment. If you like, open an issue in the Hibernate Validator issue tracker and we can explore this feature.
I'am using Hibernate / JPA as my ORM, when i use #Email and #Patern in the same field, i got two error messages.
How can i disable one of the error messages and get just one error message displayed?
Edit :
My code is below
#Email
#Pattern(regexp="Regular expression", message = "Not a valid format!")
#Target( { ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER })
#Retention(RetentionPolicy.RUNTIME)
#Constraint(validatedBy={})
#Documented
public #interface ExtendedEmailValidator {
String message() default "{org.hibernate.validator.constraints.Email.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Thanks!
Thank you for your answers, i removed #Email and fix the problem.