Jakarta ConstraintValidator: how to implement conditional validation?

3 weeks ago 27
ARTICLE AD BOX

I have a single request DTO ProfileRequest that is used by two controller endpoints:

public ResponseEntity<ProfileDto> createProfile(@Valid ProfileRequest request) { } public ResponseEntity<ProfileDto> updateProfile(@Valid ProfileRequest request) { }

Most fields are identical for both endpoints and should be validated in the same way, so I intentionally use one DTO and one custom constraint:

@ValidProfileRequest public class ProfileRequest { }

The constraint is implemented as a class-level annotation:

@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = ProfileRequestValidator.class) public @interface ValidProfileRequest { String message() default "Invalid profile request"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }

and all validation logic is handled inside ProfileRequestValidator.

The problem is that one specific field of ProfileRequest requires different validation rules depending on whether the request is handled by createProfile or updateProfile.
Everything else can and should remain identical.

Since the same DTO and validator instance are used for both endpoints, my question is:

What is the correct or idiomatic way to determine, inside ProfileRequestValidator, which scenario is currently being validated (create vs update)?

@Component public class ProfileRequestValidator implements ConstraintValidator<ValidProfileRequest, ProfileRequest> { @Override public boolean isValid(ProfileRequest request, ConstraintValidatorContext context) { ??? How to determine: create or update case??? } }

I am interested in solutions that align with Jakarta Bean Validation design principles, not ad-hoc hacks, and that avoid duplicating DTOs or validators unless that is the intended approach.

Read Entire Article