无需Hibernate的Java Bean Validation替代注解方案咨询
Great question! Since you're working with JDBI and the DAO pattern instead of ORMs like Hibernate, you don't have to miss out on convenient bean validation annotations. Here are some solid, framework-independent alternatives that fit your needs:
You mentioned the Java Bean Validation API, but here's a common misconception cleared up: you don't need Hibernate ORM to use it. Hibernate Validator is just the reference implementation of the JSR-380 standard, and it works perfectly with plain Java objects—no ORM required. This is probably the closest match to what you're looking for, especially since it supports the exact annotations you need (@Size, @Min/@Max, @NonNull).
First, add the required dependencies (no Spring or Hibernate ORM, just the validator and its API):
<!-- JSR-380 Validation API --> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>2.0.1.Final</version> </dependency> <!-- Hibernate Validator (reference implementation) --> <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>6.1.7.Final</version> </dependency> <!-- Required EL dependency for Hibernate Validator --> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.el</artifactId> <version>3.0.1-b11</version> </dependency>Annotate your bean exactly as you wanted—even pair it with Lombok for maximum convenience:
import javax.validation.constraints.Size; import javax.validation.constraints.NotNull; import javax.validation.constraints.Min; import lombok.Data; @Data // Lombok generates getters, setters, equals, hashCode, etc. class User { @NotNull @Size(max = 10) String name; @Min(18) int age; }Then validate your beans manually in your DAO layer before executing JDBI queries:
import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; import javax.validation.ConstraintViolation; import java.util.Set; public class UserDao { private final Validator validator; public UserDao() { // Initialize the validator once ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); this.validator = factory.getValidator(); } public void saveUser(User user) { // Perform validation before database operation Set<ConstraintViolation<User>> violations = validator.validate(user); if (!violations.isEmpty()) { // Handle validation errors (throw exception, log details, etc.) StringBuilder errorMsg = new StringBuilder("Invalid user data: "); for (ConstraintViolation<User> violation : violations) { errorMsg.append(String.format("%s: %s, ", violation.getPropertyPath(), violation.getMessage())); } throw new IllegalArgumentException(errorMsg.toString().trim()); } // Proceed with JDBI insert // jdbi.useHandle(handle -> // handle.createUpdate("INSERT INTO users(name, age) VALUES (:name, :age)") // .bindBean(user) // .execute() // ); } }
If you want an even lighter alternative without JSR-380, you can use Apache Commons Validator's utility methods paired with custom annotations. However, this requires writing a bit more boilerplate code to process the annotations. For example:
Add Apache Commons Validator dependency:
<dependency> <groupId>commons-validator</groupId> <artifactId>commons-validator</artifactId> <version>1.7</version> </dependency>Create custom annotations and a validator utility to check them. But honestly, this is less convenient than the JSR-380 approach, which already gives you the exact annotation syntax you want.
- Standalone JSR-380 validation is your best bet—it uses standard annotations, integrates seamlessly with Lombok, and works independently of ORMs or Spring.
- You can embed the validation step directly in your DAO layer to ensure data is valid before interacting with the database via JDBI.
- No need to tie yourself to Hibernate ORM just to use bean validation!
内容的提问来源于stack exchange,提问作者Melih

