** Bug Reports ** When reusing a class like Telephone as an @Embedded and @Valid field in multiple locations (e.g., guest, spouse as objects of Individual) in registration process and/or children to that matter, applying a class-level constraint like @ValidMobile(groups = Guest.class, Spouse.class) results in that constraint being applied across all instances of Telephone during validation where controller has been instructed to perform validation of the "Guest" along — regardless of which part of the object graph is targeted by the @Validated group. The application is unable to proceed further and if kept objects null, turning back with data handling, any issue with the Spouse (Page 2), stopping to move from Guest (Page 1).
Snippet public class RegistrationForm { @Valid @ConvertGroup(from = Default.class, to = ValidationGroup.Guest.class) private Individual guest;
@Valid @ConvertGroup(from = Default.class, to = ValidationGroup.Spouse.class) private Individual spouse; }
public class Individual { @Valid @Embedded private Telephone mobile; }
@Embeddable @ValidMobile(groups = {ValidationGroup.Guest.class, ValidationGroup.Spouse.class}) public class Telephone { private String countryCode; private String number; }
@PostMapping("/submitGuest") public String handleSubmit(@Validated(ValidationGroup.Guest.class) @ModelAttribute RegistrationForm form, BindingResult result) { // Result contains violations from both guest and spouse.telephone }
Expected Behavior Only the embedded object graph under guest should be validated for group Guest.
Actual Behavior Validation on the spouse field also triggers @ValidMobile(groups = Guest.class) because the constraint is on the shared Telephone class.
Using @ConvertGroup at the parent field — still triggers both. Moving the constraint to field level — fails if Telephone is reused in both guest and spouse. Wrapping each instance in a container object — works but is not scalable in large models. Using ThreadLocal to track active group — hacky and breaks recursive validation. @Constraint(validatedBy = …) with group filtering inside — still sees both instances. and many many....
We suggest Spring (or Bean Validation spec) support one of the following: Path-aware validation context — enable constraint evaluation only when a specific object graph path matches. Instance-aware group dispatch — constrain validators only on specific field declarations rather than types. Scoped validation hinting — allow an object field (e.g., spouse) to be excluded based on group mismatch.
Why This Matters This limitation breaks reusable modeling in: Banking Healthcare KYC / Legal workflows HR / Insurance / Visa forms Where the same sub-models (e.g., Address, Telephone, Contact) are embedded across multiple roles.
Happy to discuss and contribute in any possible way.