Explain Codes LogoExplain Codes Logo

Difference between @Valid and @Validated in Spring

java
validation
spring
best-practices
Alex KataevbyAlex Kataev·Feb 5, 2025
TLDR

Apply @Valid for JSR-380 standard validation—verifying the constraints on an object's properties are fulfilled.

public void save(@Valid User user) { /* Vestigial code just hanging around... */ }

Turn to @Validated, a Spring-centric annotation, for group validation—adjusting validations to cater for specific scenarios, say, creating versus updating operations.

public void save(@Validated(OnCreation.class) User user) { /* Only a ninja can see another ninja! */ }

Whenever you demand Spring’s enhanced arsenal, such as method-level validation or group-focused constraints, opt for @Validated. For run-of-the-mill bean validation, @Valid should suffice.

Scenario-specific validation with @Valid and @Validated

Incorporate @Valid for simple validation landscapes—where your sole aim is to ensure your object, as a whole, complies with the necessary constraints. Think nested objects:

class Order { @Valid private Customer customer; // Nested validation: Because who needs separation of concerns? //... }

@Validated, on the other hand, steals the show in the face of knotty validation requirements. It brings diverse aspects of an object to bear within different contexts—think partial updates or shifting views within a web application.

Here's a quick example of using validation groups:

public interface BasicInfo {} public interface ExtendedInfo {} public class User { @NotNull(groups = BasicInfo.class) private String username; // Actually, I'm pretty comfortable with my pseudonym! @NotNull(groups = ExtendedInfo.class) @Size(min = 10, groups = ExtendedInfo.class) private String biography; //... }

Cooking up complex logic with method-level validation

Applying @Validated at the class or interface level activates method-level validation—enabling a barrage of validations across various layers—be it service or controller layers.

@Validated public class UserService { public void updateUser(@Valid User user) { /* No points for second best here! */ } public void createUser(@Validated(OnCreate.class) User user) { /* Cooking up users, one attribute at a time... */ } }

@Validated opens up doors to complex class-level validations. In comparison, @Valid falls short on such capabilities.

Taking charge of binding results

@Validated excels when paired with a BindingResult—providing a marketplace for validation errors. Complex form submission scenarios, where errors need collecting and reporting, would greatly benefit from this.

@PostMapping("/users") public String createUser(@Validated User user, BindingResult result) { if (result.hasErrors()) { // Handle errors. return "form"; } // Success is not a destination, it’s a journey! return "success"; }

@Validated truly shines in complex scenarios such as multi-step forms, where divergent validations might be mandatory at each step. Equally, @Validated comes in handy with dynamic forms, where varying field sets are subject to user choice and demand targeted validation norms.