CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-jakarta-validation--jakarta-validation-api

Jakarta Validation API defines a metadata model and API for JavaBean and method validation

Pending
Overview
Eval results
Files

validation-groups.mddocs/

Validation Groups

Group-based validation for conditional constraint application and validation sequencing with group conversion support during cascading validation.

Capabilities

Default Group

Marker interface representing the default validation group.

/**
 * Default validation group
 * Constraints belong to this group unless explicitly assigned to other groups
 */
interface Default {}

Group Sequence

Annotation for defining sequential validation of groups.

/**
 * Defines a sequence of groups that should be validated sequentially
 * If validation fails for one group, subsequent groups are not validated
 */
@Target({TYPE})
@Retention(RUNTIME)
@interface GroupSequence {
    /**
     * The sequence of groups to validate
     * @return array of group classes
     */
    Class<?>[] value();
}

Group Conversion

Annotation for converting validation groups during cascading validation.

/**
 * Converts validation groups during cascaded validation
 * Applied to fields, method parameters, and return values marked with @Valid
 */
@Target({FIELD, METHOD, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Repeatable(ConvertGroup.List.class)
@interface ConvertGroup {
    /**
     * The source group to convert from
     * @return source group class
     */
    Class<?> from();
    
    /**
     * The target group to convert to  
     * @return target group class
     */
    Class<?> to();
    
    /**
     * Container for multiple ConvertGroup annotations
     */
    @Target({FIELD, METHOD, CONSTRUCTOR, PARAMETER, TYPE_USE})
    @Retention(RUNTIME)
    @interface List {
        ConvertGroup[] value();
    }
}

Usage Examples:

import jakarta.validation.*;
import jakarta.validation.constraints.*;
import jakarta.validation.groups.*;

// 1. Define validation groups
interface BasicInfo {}
interface AdvancedInfo {}
interface AdminInfo {}

// 2. Apply constraints to specific groups
public class User {
    @NotNull(groups = {BasicInfo.class, AdvancedInfo.class})
    @Size(min = 2, max = 50, groups = BasicInfo.class)
    private String name;
    
    @NotNull(groups = BasicInfo.class)
    @Email(groups = BasicInfo.class)
    private String email;
    
    @Min(value = 18, groups = AdvancedInfo.class)
    private Integer age;
    
    @NotNull(groups = AdminInfo.class)
    private String adminRole;
    
    // constructors, getters, setters...
}

// 3. Group sequence for ordered validation
@GroupSequence({BasicInfo.class, AdvancedInfo.class, AdminInfo.class})
interface UserValidationSequence {}

// 4. Validate with specific groups
public class ValidationGroupExample {
    private Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
    
    public void validateUserGroups() {
        User user = new User();
        user.setName(""); // Invalid for BasicInfo
        user.setAge(15);  // Invalid for AdvancedInfo
        
        // Validate only basic information
        Set<ConstraintViolation<User>> basicViolations = 
            validator.validate(user, BasicInfo.class);
        System.out.println("Basic validation violations: " + basicViolations.size());
        
        // Validate advanced information  
        Set<ConstraintViolation<User>> advancedViolations = 
            validator.validate(user, AdvancedInfo.class);
        System.out.println("Advanced validation violations: " + advancedViolations.size());
        
        // Validate with sequence (stops at first failing group)
        Set<ConstraintViolation<User>> sequenceViolations = 
            validator.validate(user, UserValidationSequence.class);
        System.out.println("Sequence validation violations: " + sequenceViolations.size());
        
        // Validate multiple groups at once
        Set<ConstraintViolation<User>> multiGroupViolations = 
            validator.validate(user, BasicInfo.class, AdvancedInfo.class);
        System.out.println("Multi-group validation violations: " + multiGroupViolations.size());
    }
}

// 5. Group conversion in cascading validation
public class Order {
    @NotNull
    @Valid
    @ConvertGroup(from = Default.class, to = BasicInfo.class)
    private User customer;  // When validating Order, customer uses BasicInfo group
    
    @Valid
    @ConvertGroup(from = BasicInfo.class, to = AdvancedInfo.class)
    @ConvertGroup(from = AdvancedInfo.class, to = AdminInfo.class)
    private User assignedAgent;  // Multiple group conversions
    
    @NotNull(groups = BasicInfo.class)
    private String orderNumber;
    
    // constructors, getters, setters...
}

// 6. Dynamic group validation
public class UserRegistrationService {
    private Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
    
    public ValidationResult validateUser(User user, String validationLevel) {
        Class<?>[] groups;
        
        switch (validationLevel) {
            case "basic":
                groups = new Class<?>[]{BasicInfo.class};
                break;
            case "advanced":  
                groups = new Class<?>[]{BasicInfo.class, AdvancedInfo.class};
                break;
            case "admin":
                groups = new Class<?>[]{UserValidationSequence.class};
                break;
            default:
                groups = new Class<?>[]{Default.class};
        }
        
        Set<ConstraintViolation<User>> violations = validator.validate(user, groups);
        return new ValidationResult(violations.isEmpty(), violations);
    }
}

// 7. Conditional validation based on object state
public class ConditionalUser {
    @NotNull
    private String username;
    
    @NotNull(groups = PremiumUser.class)
    @Size(min = 10, groups = PremiumUser.class)
    private String premiumFeature;
    
    private boolean isPremium;
    
    public Set<ConstraintViolation<ConditionalUser>> validate() {
        Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
        
        if (isPremium) {
            return validator.validate(this, Default.class, PremiumUser.class);
        } else {
            return validator.validate(this, Default.class);
        }
    }
    
    interface PremiumUser {}
}

Install with Tessl CLI

npx tessl i tessl/maven-jakarta-validation--jakarta-validation-api

docs

bean-validation.md

bootstrap-configuration.md

constraints.md

container-validation.md

custom-constraints.md

index.md

metadata.md

method-validation.md

validation-groups.md

tile.json