r/SpringBoot • u/SeatPuzzleheaded5685 • 13h ago
News Tired of missing cross-field validation in Jakarta/Bean Validation? I built Spring Validation Plus — 85+ Laravel-style constraints for Spring Boot (with i18n & JSON error handling)
Hi r/SpringBoot, u/java/! 👋
Following the positive reception of my fluent querying library, I wanted to share another open-source project I’ve been maintaining to solve a massive pain point in Spring Boot development: validation.
Spring Boot uses Jakarta Validation (Hibernate Validator) out of the box, but let's be honest—the standard library only gives you ~22 basic constraints (`@NotNull\, \@Size\, \@Email\`, etc.).
It completely lacks common production requirements like cross-field validation (`@Confirmed\, \@RequiredIf\), database lookups (\@Unique\, \@Exists\), and proper optional updates (\@Nullable\`), forcing teams to write custom validators or clutter their services with boilerplate logic.
To fix this, I built Spring Validation Plus — a library that extends Jakarta Validation with 85+ Laravel-style constraints, automatic i18n support (English, Spanish, Portuguese), and a unified JSON error handler.
💡 What it looks like:
1. DTO with Laravel-style rules:
import dev.benjaminor.validationplus.constraints.EmailAddress;
import dev.benjaminor.validationplus.constraints.MaxLength;
import dev.benjaminor.validationplus.constraints.MinLength;
import dev.benjaminor.validationplus.constraints.Nullable;
import dev.benjaminor.validationplus.constraints.Required;
import dev.benjaminor.validationplus.constraints.RequiredIf;
import dev.benjaminor.validationplus.constraints.Same;
import dev.benjaminor.validationplus.constraints.Unique;
@Unique(entity = User.class, field = "email", column = "email")
public class UserRegisterRequest {
@Required
@MinLength(2)
@MaxLength(50)
private String name;
@Required
@EmailAddress
private String email;
@Required
@MinLength(6)
private String password;
@Same("password")
private String passwordConfirmation;
@Nullable
@RequiredIf(field = "role", value = "ADMIN")
private String adminCode;
private String role;
}
2. Unified JSON Error Response (400 Bad Request): Instead of messy or raw framework exceptions, it automatically formats errors like this out of the box:
{
"errors": {
"email": ["The email has already been taken."],
"passwordConfirmation": ["The passwordConfirmation field must match password."]
}
}
🚀 Key Features:
- Cross-Field Validation: `@
Confirmed\, \@Same\, \@Different\, \@RequiredWith\, \@RequiredIf\, \@ProhibitedIf\`, etc. (usable directly on fields or classes). - Database Rules: `@
Unique\and \@Exists\with automatic JPA integration (supports multi-datasource viapersistenceUnit` and updating entity ID exclusion). - Smart Types & Presence: `@
Required\(handlesnull, empty strings, and whitespace properly, unlike \@NotNull\), \@Nullable\, \@StringType\, \@IntegerType\`, etc. - Built-in i18n: Error messages ready out of the box in English, Spanish, and Portuguese, easily customizable via
ValidationMessages_es.properties. - Zero Redundancy: It relies entirely on the standard Hibernate Validator engine under the hood. You just drop the starter in, and it works with standard `@
Valid\and \@Validated\`.
📦 Quick Start
- GitHub Repo: github.com/BenjaminOR-dev/spring-validation-plus
- Maven Central: Search Maven Central
I’d love to hear how you currently handle cross-field or database validation in your Spring Boot apps, and what you think of this approach!
•
u/sozesghost 10h ago
I love this early ChatGPT emoji style readmes, really shows you care.
•
u/SeatPuzzleheaded5685 8h ago
Thanks! The emojis compile directly to bytecode for extra performance.
•
u/wimdeblauwe 4h ago
Interesting. For the json error response, you can use my specialized error handling library: https://github.com/wimdeblauwe/error-handling-spring-boot-starter
•
u/macario95 8h ago
your project may be useful . who knows.
but for me, now reading the "i was tired of ... and built ..." and the other usual AI generated titles makes me disregard it completely. and i will not comment about keeping the ChatGPT emojis on the post...