CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-hibernate-validator--hibernate-validator

Hibernate Validator is the reference implementation of Jakarta Validation 3.1 providing annotation-based validation for JavaBeans and method parameters

Overview
Eval results
Files

spi.mddocs/

Service Provider Interfaces

Comprehensive SPI for extending Hibernate Validator including constraint mapping contributors, dynamic group sequence providers, custom locale resolvers, property node name providers, getter property selection strategies, resource bundle locators, and script evaluator factories.

Capabilities

Constraint Mapping Contributor SPI

Contribute constraint mappings programmatically during validator factory creation.

package org.hibernate.validator.spi.cfg;

import org.hibernate.validator.cfg.ConstraintMapping;

/**
 * Contributes constraint mappings to validator configuration.
 * Implementations are discovered via ServiceLoader or configured explicitly.
 */
interface ConstraintMappingContributor {
    /**
     * Create and add constraint mappings to builder.
     *
     * @param builder constraint mapping builder
     */
    void createConstraintMappings(ConstraintMappingBuilder builder);

    /**
     * Builder for adding constraint mappings.
     */
    interface ConstraintMappingBuilder {
        /**
         * Add new constraint mapping to configuration.
         *
         * @return newly created constraint mapping for fluent configuration
         */
        ConstraintMapping addConstraintMapping();
    }
}

Usage Example:

import org.hibernate.validator.spi.cfg.ConstraintMappingContributor;
import org.hibernate.validator.cfg.ConstraintMapping;
import org.hibernate.validator.cfg.defs.*;
import static java.lang.annotation.ElementType.*;

/**
 * Contributor that adds validation constraints for all User entities.
 */
public class UserConstraintContributor implements ConstraintMappingContributor {

    @Override
    public void createConstraintMappings(ConstraintMappingBuilder builder) {
        // Add user constraints
        builder.addConstraintMapping()
            .type(User.class)
                .field("username")
                    .constraint(new NotBlankDef())
                    .constraint(new LengthDef().min(3).max(50))
                .field("email")
                    .constraint(new NotBlankDef())
                    .constraint(new EmailDef())
                .field("age")
                    .constraint(new MinDef().value(18))
                    .constraint(new MaxDef().value(120));

        // Add address constraints
        builder.addConstraintMapping()
            .type(Address.class)
                .field("street")
                    .constraint(new NotBlankDef())
                .field("zipCode")
                    .constraint(new NotBlankDef())
                    .constraint(new PatternDef().regexp("[0-9]{5}"));
    }
}

// Register via ServiceLoader:
// Create META-INF/services/org.hibernate.validator.spi.cfg.ConstraintMappingContributor
// Add line: com.example.UserConstraintContributor

// Or configure explicitly:
ValidatorFactory factory = Validation.byProvider(HibernateValidator.class)
    .configure()
    .addProperty(
        BaseHibernateValidatorConfiguration.CONSTRAINT_MAPPING_CONTRIBUTORS,
        "com.example.UserConstraintContributor"
    )
    .buildValidatorFactory();

Group Sequence Provider SPI

Provide default group sequence dynamically at validation time.

package org.hibernate.validator.spi.group;

import java.util.List;

/**
 * Provides default group sequence for given type dynamically.
 * Allows group sequence to depend on object state.
 *
 * @param <T> type for which to provide default group sequence
 */
interface DefaultGroupSequenceProvider<T> {
    /**
     * Returns validation groups for given object.
     * The Default group will be replaced by returned groups.
     *
     * @param object object being validated
     * @return list of validation groups
     */
    List<Class<?>> getValidationGroups(T object);
}

/**
 * Annotation that specifies the DefaultGroupSequenceProvider implementation
 * for dynamic group sequence resolution.
 *
 * Applied to bean types to enable state-dependent validation group ordering.
 * Cannot be used together with @GroupSequence.
 *
 * This is a Hibernate Validator specific annotation (not portable).
 *
 * @see DefaultGroupSequenceProvider
 * @see jakarta.validation.GroupSequence
 */
package org.hibernate.validator.group;

import java.lang.annotation.*;
import org.hibernate.validator.spi.group.DefaultGroupSequenceProvider;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface GroupSequenceProvider {
    /**
     * The DefaultGroupSequenceProvider implementation to use.
     *
     * @return default group sequence provider class
     */
    Class<? extends DefaultGroupSequenceProvider<?>> value();
}

Usage Example:

import org.hibernate.validator.spi.group.DefaultGroupSequenceProvider;
import org.hibernate.validator.group.GroupSequenceProvider;
import jakarta.validation.constraints.*;
import java.util.*;

// Define validation groups
interface BasicChecks {}
interface PremiumChecks {}
interface AdminChecks {}

// Entity with dynamic group sequence
@GroupSequenceProvider(UserGroupSequenceProvider.class)
class User {
    @NotNull
    private String username;

    @NotNull(groups = BasicChecks.class)
    @Email(groups = BasicChecks.class)
    private String email;

    @NotNull(groups = PremiumChecks.class)
    @Pattern(regexp = "\\d{3}-\\d{3}-\\d{4}", groups = PremiumChecks.class)
    private String phoneNumber;

    @NotNull(groups = AdminChecks.class)
    private String adminToken;

    private UserType userType;

    // getters/setters...
}

enum UserType {
    BASIC, PREMIUM, ADMIN
}

/**
 * Provides dynamic group sequence based on user type.
 */
class UserGroupSequenceProvider implements DefaultGroupSequenceProvider<User> {

    @Override
    public List<Class<?>> getValidationGroups(User user) {
        List<Class<?>> groups = new ArrayList<>();

        // Always include Default group
        groups.add(User.class);

        if (user == null) {
            return groups;
        }

        // Add groups based on user type
        switch (user.getUserType()) {
            case BASIC:
                groups.add(BasicChecks.class);
                break;
            case PREMIUM:
                groups.add(BasicChecks.class);
                groups.add(PremiumChecks.class);
                break;
            case ADMIN:
                groups.add(BasicChecks.class);
                groups.add(PremiumChecks.class);
                groups.add(AdminChecks.class);
                break;
        }

        return groups;
    }
}

// Usage
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

// Basic user - only basic checks
User basicUser = new User();
basicUser.setUserType(UserType.BASIC);
Set<ConstraintViolation<User>> violations = validator.validate(basicUser);
// Validates: username, email

// Premium user - basic + premium checks
User premiumUser = new User();
premiumUser.setUserType(UserType.PREMIUM);
violations = validator.validate(premiumUser);
// Validates: username, email, phoneNumber

// Admin user - all checks
User adminUser = new User();
adminUser.setUserType(UserType.ADMIN);
violations = validator.validate(adminUser);
// Validates: username, email, phoneNumber, adminToken

Locale Resolver SPI

Resolve locale dynamically for message interpolation.

package org.hibernate.validator.spi.messageinterpolation;

import java.util.Locale;

/**
 * Resolves locale for message interpolation.
 * Allows dynamic locale selection based on context.
 *
 * @since 6.1.1
 */
@Incubating
interface LocaleResolver {
    /**
     * Resolve locale for given context.
     *
     * @param context locale resolution context
     * @return resolved locale
     */
    Locale resolve(LocaleResolverContext context);
}

/**
 * Context for locale resolution.
 *
 * @since 6.1.1
 */
@Incubating
interface LocaleResolverContext {
    /**
     * Get default locale configured for validator factory.
     *
     * @return default locale
     */
    Locale getDefaultLocale();

    /**
     * Get set of supported locales configured for validator factory.
     *
     * @return supported locales
     */
    java.util.Set<Locale> getSupportedLocales();
}

Usage Example:

import org.hibernate.validator.spi.messageinterpolation.LocaleResolver;
import org.hibernate.validator.spi.messageinterpolation.LocaleResolverContext;
import org.hibernate.validator.HibernateValidator;
import jakarta.validation.*;
import java.util.*;

/**
 * Locale resolver that uses thread-local context.
 */
class ThreadLocalLocaleResolver implements LocaleResolver {

    private static final ThreadLocal<Locale> LOCALE_HOLDER = new ThreadLocal<>();

    public static void setLocale(Locale locale) {
        LOCALE_HOLDER.set(locale);
    }

    public static void clearLocale() {
        LOCALE_HOLDER.remove();
    }

    @Override
    public Locale resolve(LocaleResolverContext context) {
        Locale locale = LOCALE_HOLDER.get();

        if (locale != null && context.getSupportedLocales().contains(locale)) {
            return locale;
        }

        // Fall back to default locale
        return context.getDefaultLocale();
    }
}

// Configure validator
LocaleResolver localeResolver = new ThreadLocalLocaleResolver();

ValidatorFactory factory = Validation.byProvider(HibernateValidator.class)
    .configure()
    .locales(Locale.US, Locale.FRANCE, Locale.GERMANY)
    .defaultLocale(Locale.US)
    .localeResolver(localeResolver)
    .buildValidatorFactory();

Validator validator = factory.getValidator();

// Use with different locales per thread
ThreadLocalLocaleResolver.setLocale(Locale.FRANCE);
Set<ConstraintViolation<User>> violations = validator.validate(user);
// Messages interpolated in French

ThreadLocalLocaleResolver.setLocale(Locale.GERMANY);
violations = validator.validate(user);
// Messages interpolated in German

ThreadLocalLocaleResolver.clearLocale();

Property Node Name Provider SPI

Resolve property node names dynamically in validation paths.

package org.hibernate.validator.spi.nodenameprovider;

/**
 * Resolves property node name when creating property path.
 * Allows customizing how property names appear in constraint violations.
 *
 * @since 6.1.0
 */
@Incubating
interface PropertyNodeNameProvider {
    /**
     * Get name for property.
     *
     * @param property property to resolve name for
     * @return property name
     */
    String getName(Property property);
}

/**
 * Represents a property for name resolution.
 */
@Incubating
interface Property {
    /**
     * Get property name.
     *
     * @return property name
     */
    String getName();
}

/**
 * Represents JavaBean property with additional metadata.
 */
@Incubating
interface JavaBeanProperty extends Property {
    /**
     * Get declaring class.
     *
     * @return class declaring this property
     */
    Class<?> getDeclaringClass();

    /**
     * Get property type.
     *
     * @return property type
     */
    Class<?> getType();
}

Usage Example:

import org.hibernate.validator.spi.nodenameprovider.*;
import org.hibernate.validator.HibernateValidator;
import jakarta.validation.*;
import java.lang.reflect.Field;

/**
 * Property node name provider using @JsonProperty annotation names.
 */
class JsonPropertyNodeNameProvider implements PropertyNodeNameProvider {

    @Override
    public String getName(Property property) {
        if (property instanceof JavaBeanProperty) {
            JavaBeanProperty javaProperty = (JavaBeanProperty) property;

            // Try to find @JsonProperty annotation
            try {
                Field field = javaProperty.getDeclaringClass()
                    .getDeclaredField(property.getName());

                JsonProperty jsonProperty = field.getAnnotation(JsonProperty.class);
                if (jsonProperty != null && !jsonProperty.value().isEmpty()) {
                    return jsonProperty.value();
                }
            } catch (NoSuchFieldException e) {
                // Fall through to default name
            }
        }

        // Use default property name
        return property.getName();
    }
}

// Example annotation
@interface JsonProperty {
    String value();
}

// Example entity
class ApiRequest {
    @JsonProperty("user_name")
    @NotBlank
    private String userName;

    @JsonProperty("email_address")
    @Email
    private String emailAddress;

    // getters/setters...
}

// Configure validator
PropertyNodeNameProvider nameProvider = new JsonPropertyNodeNameProvider();

ValidatorFactory factory = Validation.byProvider(HibernateValidator.class)
    .configure()
    .propertyNodeNameProvider(nameProvider)
    .buildValidatorFactory();

Validator validator = factory.getValidator();

ApiRequest request = new ApiRequest();
Set<ConstraintViolation<ApiRequest>> violations = validator.validate(request);

for (ConstraintViolation<ApiRequest> violation : violations) {
    // Property path uses JSON names: "user_name", "email_address"
    System.out.println(violation.getPropertyPath());
}

Getter Property Selection Strategy SPI

Define strategy for detecting JavaBean getters.

package org.hibernate.validator.spi.properties;

import java.util.List;
import java.util.Optional;

/**
 * Defines strategy for detecting getters of a bean.
 * Determines which methods are considered JavaBean getters.
 *
 * @since 6.1.0
 */
@Incubating
interface GetterPropertySelectionStrategy {
    /**
     * Determine if method is a getter and return property name.
     *
     * @param executable method to check
     * @return Optional containing property name if method is getter, empty otherwise
     */
    Optional<String> getProperty(ConstrainableExecutable executable);

    /**
     * Get possible getter method names for property name.
     *
     * @param propertyName property name
     * @return list of possible getter method names
     */
    List<String> getGetterMethodNameCandidates(String propertyName);
}

/**
 * Represents an executable (method or constructor) that can be constrained.
 */
@Incubating
interface ConstrainableExecutable {
    /**
     * Get method/constructor name.
     *
     * @return executable name
     */
    String getName();

    /**
     * Get return type.
     *
     * @return return type
     */
    Class<?> getReturnType();

    /**
     * Get parameter types.
     *
     * @return parameter types
     */
    Class<?>[] getParameterTypes();

    /**
     * Check if this is a method.
     *
     * @return true if method, false if constructor
     */
    boolean isMethod();
}

Usage Example:

import org.hibernate.validator.spi.properties.*;
import org.hibernate.validator.HibernateValidator;
import jakarta.validation.*;
import java.util.*;

/**
 * Custom getter selection strategy supporting "read" prefix.
 * Recognizes: get, is, has, read
 */
class ExtendedGetterSelectionStrategy implements GetterPropertySelectionStrategy {

    @Override
    public Optional<String> getProperty(ConstrainableExecutable executable) {
        if (!executable.isMethod()) {
            return Optional.empty();
        }

        String methodName = executable.getName();
        Class<?> returnType = executable.getReturnType();
        Class<?>[] paramTypes = executable.getParameterTypes();

        // Must have no parameters
        if (paramTypes.length != 0) {
            return Optional.empty();
        }

        // Must have return value
        if (returnType == void.class) {
            return Optional.empty();
        }

        // Check standard patterns
        if (methodName.startsWith("get") && methodName.length() > 3) {
            return Optional.of(decapitalize(methodName.substring(3)));
        }

        if (methodName.startsWith("is") && methodName.length() > 2 &&
            (returnType == boolean.class || returnType == Boolean.class)) {
            return Optional.of(decapitalize(methodName.substring(2)));
        }

        if (methodName.startsWith("has") && methodName.length() > 3) {
            return Optional.of(decapitalize(methodName.substring(3)));
        }

        // Custom: support "read" prefix
        if (methodName.startsWith("read") && methodName.length() > 4) {
            return Optional.of(decapitalize(methodName.substring(4)));
        }

        return Optional.empty();
    }

    @Override
    public List<String> getGetterMethodNameCandidates(String propertyName) {
        String capitalized = capitalize(propertyName);

        return Arrays.asList(
            "get" + capitalized,
            "is" + capitalized,
            "has" + capitalized,
            "read" + capitalized  // Custom
        );
    }

    private String decapitalize(String string) {
        if (string.isEmpty()) {
            return string;
        }
        return Character.toLowerCase(string.charAt(0)) + string.substring(1);
    }

    private String capitalize(String string) {
        if (string.isEmpty()) {
            return string;
        }
        return Character.toUpperCase(string.charAt(0)) + string.substring(1);
    }
}

// Configure validator
GetterPropertySelectionStrategy strategy = new ExtendedGetterSelectionStrategy();

ValidatorFactory factory = Validation.byProvider(HibernateValidator.class)
    .configure()
    .getterPropertySelectionStrategy(strategy)
    .buildValidatorFactory();

// Now methods like readProperty() are recognized as getters
class Document {
    private String content;

    @NotBlank  // Will validate the property via readContent()
    public String readContent() {
        return content;
    }
}

Resource Bundle Locator SPI

SPI for custom resource bundle loading strategies.

package org.hibernate.validator.spi.resourceloading;

import java.util.Locale;
import java.util.ResourceBundle;

/**
 * Locates resource bundles for message interpolation.
 * Implement to provide custom resource bundle loading.
 */
interface ResourceBundleLocator {
    /**
     * Get resource bundle for specified locale.
     *
     * @param locale locale for bundle
     * @return resource bundle
     */
    ResourceBundle getResourceBundle(Locale locale);
}

Usage Example: See Resource Bundle Loading for detailed examples.

Script Evaluator Factory SPI

Factory for creating script evaluators for @ScriptAssert constraints.

package org.hibernate.validator.spi.scripting;

/**
 * Factory for creating ScriptEvaluators.
 * Implement to provide custom script evaluation.
 *
 * @since 6.0.3
 */
@Incubating
interface ScriptEvaluatorFactory {
    /**
     * Get script evaluator for specified language.
     *
     * @param languageName script language name
     * @return script evaluator
     * @throws ScriptEvaluatorNotFoundException if language not supported
     */
    ScriptEvaluator getScriptEvaluatorByLanguageName(String languageName);

    /**
     * Clear factory state (caches, etc.).
     */
    void clear();
}

/**
 * Evaluates script expressions.
 */
@Incubating
interface ScriptEvaluator {
    /**
     * Evaluate script expression.
     *
     * @param script script to evaluate
     * @param bindings variables available in script
     * @return evaluation result
     * @throws ScriptEvaluationException if evaluation fails
     */
    Object evaluate(String script, java.util.Map<String, Object> bindings)
        throws ScriptEvaluationException;
}

/**
 * Base class for script evaluator factories with caching.
 */
@Incubating
abstract class AbstractCachingScriptEvaluatorFactory implements ScriptEvaluatorFactory {
    /**
     * Get or create cached script evaluator.
     *
     * @param languageName language name
     * @return cached script evaluator
     */
    protected abstract ScriptEvaluator createScriptEvaluator(String languageName);

    @Override
    public final ScriptEvaluator getScriptEvaluatorByLanguageName(String languageName) {
        // Caching implementation
    }

    @Override
    public void clear() {
        // Clear cache
    }
}

/**
 * ScriptEvaluator using javax.script.ScriptEngine.
 */
@Incubating
class ScriptEngineScriptEvaluator implements ScriptEvaluator {
    /**
     * Create evaluator for script engine.
     *
     * @param scriptEngine JSR 223 script engine
     */
    ScriptEngineScriptEvaluator(javax.script.ScriptEngine scriptEngine);

    @Override
    Object evaluate(String script, java.util.Map<String, Object> bindings);
}

// Exception classes
class ScriptEvaluationException extends RuntimeException {
    ScriptEvaluationException(String message);
    ScriptEvaluationException(String message, Throwable cause);
}

class ScriptEvaluatorNotFoundException extends RuntimeException {
    ScriptEvaluatorNotFoundException(String message);
}

Usage Example:

import org.hibernate.validator.spi.scripting.*;
import org.hibernate.validator.HibernateValidator;
import jakarta.validation.*;
import javax.script.*;
import java.util.*;

/**
 * Custom script evaluator factory with security restrictions.
 */
class SecureScriptEvaluatorFactory extends AbstractCachingScriptEvaluatorFactory {

    @Override
    protected ScriptEvaluator createScriptEvaluator(String languageName) {
        if (!"javascript".equalsIgnoreCase(languageName)) {
            throw new ScriptEvaluatorNotFoundException(
                "Only JavaScript is supported");
        }

        // Create sandboxed JavaScript engine
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("javascript");

        if (engine == null) {
            throw new ScriptEvaluatorNotFoundException(
                "JavaScript engine not available");
        }

        // Apply security restrictions
        configureSecurityRestrictions(engine);

        return new ScriptEngineScriptEvaluator(engine);
    }

    private void configureSecurityRestrictions(ScriptEngine engine) {
        // Restrict access to dangerous classes/methods
        // Implementation depends on script engine
    }
}

// Configure validator
ScriptEvaluatorFactory scriptFactory = new SecureScriptEvaluatorFactory();

ValidatorFactory factory = Validation.byProvider(HibernateValidator.class)
    .configure()
    .scriptEvaluatorFactory(scriptFactory)
    .buildValidatorFactory();

// Use @ScriptAssert constraints
@ScriptAssert(
    lang = "javascript",
    script = "_this.endDate > _this.startDate",
    message = "End date must be after start date"
)
class DateRange {
    private Date startDate;
    private Date endDate;
    // getters/setters...
}

Parameter Name Provider Implementation

Hibernate Validator provides an alternative parameter name provider implementation using the ParaNamer library.

package org.hibernate.validator.parameternameprovider;

import jakarta.validation.ParameterNameProvider;
import com.thoughtworks.paranamer.Paranamer;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.List;

/**
 * ParameterNameProvider implementation backed by the ParaNamer library.
 * Extracts parameter names from debug information or other sources.
 *
 * The ParaNamer implementation can be customized via constructor.
 * By default uses AdaptiveParanamer wrapped in CachingParanamer.
 * Falls back to default parameter names if ParaNamer cannot retrieve names.
 *
 * Requires ParaNamer library on classpath.
 *
 * @see <a href="http://paranamer.codehaus.org/">ParaNamer web site</a>
 */
class ParanamerParameterNameProvider implements ParameterNameProvider {
    /**
     * Create provider with default Paranamer (AdaptiveParanamer with caching).
     */
    ParanamerParameterNameProvider();

    /**
     * Create provider with custom Paranamer implementation.
     *
     * @param paranamer custom paranamer implementation, null for default
     */
    ParanamerParameterNameProvider(Paranamer paranamer);

    /**
     * Get parameter names for constructor.
     * Falls back to default names if ParaNamer cannot retrieve them.
     *
     * @param constructor the constructor
     * @return list of parameter names
     */
    List<String> getParameterNames(Constructor<?> constructor);

    /**
     * Get parameter names for method.
     * Falls back to default names if ParaNamer cannot retrieve them.
     *
     * @param method the method
     * @return list of parameter names
     */
    List<String> getParameterNames(Method method);
}

Usage Example:

import org.hibernate.validator.parameternameprovider.ParanamerParameterNameProvider;
import jakarta.validation.*;
import jakarta.validation.constraints.*;
import jakarta.validation.executable.*;

// 1. Configure validator factory with ParanamerParameterNameProvider
ValidatorFactory factory = Validation.byDefaultProvider()
    .configure()
    .parameterNameProvider(new ParanamerParameterNameProvider())
    .buildValidatorFactory();

Validator validator = factory.getValidator();
ExecutableValidator executableValidator = validator.forExecutables();

// 2. Bean with validated method
class UserService {
    /**
     * Create new user with validation.
     * When compiled with debug information (-g flag), parameter names
     * are preserved and used in validation messages.
     */
    public User createUser(
        @NotNull @Size(min = 3, max = 50) String username,
        @NotNull @Email String email,
        @Min(18) int age
    ) {
        return new User(username, email, age);
    }
}

// 3. Validate method parameters
UserService service = new UserService();
Method method = UserService.class.getMethod("createUser", String.class, String.class, int.class);

Object[] params = {"jo", "invalid", 15};  // All parameters invalid

Set<ConstraintViolation<UserService>> violations = executableValidator.validateParameters(
    service,
    method,
    params
);

// With ParaNamer, violation messages use actual parameter names:
// - "createUser.username: size must be between 3 and 50"
// - "createUser.email: must be a well-formed email address"
// - "createUser.age: must be greater than or equal to 18"
//
// Without ParaNamer, generic names would be used:
// - "createUser.arg0: size must be between 3 and 50"
// - "createUser.arg1: must be a well-formed email address"
// - "createUser.arg2: must be greater than or equal to 18"

Complete SPI Integration Example

import org.hibernate.validator.*;
import org.hibernate.validator.spi.cfg.ConstraintMappingContributor;
import org.hibernate.validator.spi.group.DefaultGroupSequenceProvider;
import org.hibernate.validator.spi.messageinterpolation.*;
import org.hibernate.validator.spi.nodenameprovider.*;
import org.hibernate.validator.spi.properties.*;
import org.hibernate.validator.spi.scripting.*;
import jakarta.validation.*;
import java.util.*;

/**
 * Complete custom validation configuration using all SPIs.
 */
class CustomValidationConfiguration {

    public ValidatorFactory createValidatorFactory() {
        // Create SPI implementations
        ConstraintMappingContributor mappingContributor = new CustomMappingContributor();
        LocaleResolver localeResolver = new ThreadLocalLocaleResolver();
        PropertyNodeNameProvider nodeNameProvider = new JsonPropertyNodeNameProvider();
        GetterPropertySelectionStrategy getterStrategy = new ExtendedGetterSelectionStrategy();
        ScriptEvaluatorFactory scriptFactory = new SecureScriptEvaluatorFactory();

        // Configure validator factory
        return Validation.byProvider(HibernateValidator.class)
            .configure()
            // Add constraint mapping contributor
            .addProperty(
                BaseHibernateValidatorConfiguration.CONSTRAINT_MAPPING_CONTRIBUTORS,
                CustomMappingContributor.class.getName()
            )
            // Configure locale resolution
            .locales(Locale.US, Locale.FRANCE, Locale.GERMANY)
            .defaultLocale(Locale.US)
            .localeResolver(localeResolver)
            // Configure property name resolution
            .propertyNodeNameProvider(nodeNameProvider)
            // Configure getter detection
            .getterPropertySelectionStrategy(getterStrategy)
            // Configure script evaluation
            .scriptEvaluatorFactory(scriptFactory)
            // Other settings
            .failFast(false)
            .constraintExpressionLanguageFeatureLevel(
                ExpressionLanguageFeatureLevel.BEAN_PROPERTIES)
            .buildValidatorFactory();
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-org-hibernate-validator--hibernate-validator

docs

configuration.md

constraint-validation.md

constraints.md

index.md

message-interpolation.md

path-navigation.md

programmatic-config.md

resource-loading.md

spi.md

tile.json