Hibernate Validator is the reference implementation of Jakarta Validation 3.1 providing annotation-based validation for JavaBeans and method parameters
Bootstrap and configure Hibernate Validator with comprehensive options for controlling validation behavior, including fail-fast modes, method constraint validation rules, Expression Language feature levels, temporal validation tolerance, resource bundle locations, and predefined scope validation for build-time optimization.
Bootstrap Hibernate Validator as the validation provider for full-scope validation with runtime constraint discovery.
package org.hibernate.validator;
import jakarta.validation.Configuration;
import jakarta.validation.ValidatorFactory;
import jakarta.validation.spi.BootstrapState;
import jakarta.validation.spi.ConfigurationState;
import jakarta.validation.spi.ValidationProvider;
/**
* Default implementation of ValidationProvider within Hibernate Validator.
* Main entry point for bootstrapping with full scope validation.
*/
class HibernateValidator implements ValidationProvider<HibernateValidatorConfiguration> {
/**
* Create Hibernate Validator specific configuration.
*
* @param state bootstrap state
* @return Hibernate Validator configuration
*/
HibernateValidatorConfiguration createSpecializedConfiguration(BootstrapState state);
/**
* Create generic Jakarta Validation configuration.
*
* @param state bootstrap state
* @return generic configuration
*/
Configuration<?> createGenericConfiguration(BootstrapState state);
/**
* Build ValidatorFactory from configuration state.
*
* @param configurationState configuration state
* @return validator factory
*/
ValidatorFactory buildValidatorFactory(ConfigurationState configurationState);
}Usage Example:
import jakarta.validation.Validation;
import jakarta.validation.ValidatorFactory;
import org.hibernate.validator.HibernateValidator;
// Bootstrap using Hibernate Validator provider
ValidatorFactory factory = Validation
.byProvider(HibernateValidator.class)
.configure()
.buildValidatorFactory();Base interface containing all Hibernate-specific configuration options. Should not be used directly - use HibernateValidatorConfiguration or PredefinedScopeHibernateValidatorConfiguration instead.
package org.hibernate.validator;
import jakarta.validation.Configuration;
import jakarta.validation.TraversableResolver;
import java.time.Duration;
import java.util.Locale;
import java.util.Set;
import org.hibernate.validator.cfg.ConstraintMapping;
import org.hibernate.validator.messageinterpolation.ExpressionLanguageFeatureLevel;
import org.hibernate.validator.metadata.BeanMetaDataClassNormalizer;
import org.hibernate.validator.spi.messageinterpolation.LocaleResolver;
import org.hibernate.validator.spi.nodenameprovider.PropertyNodeNameProvider;
import org.hibernate.validator.spi.properties.GetterPropertySelectionStrategy;
import org.hibernate.validator.spi.resourceloading.ResourceBundleLocator;
import org.hibernate.validator.spi.scripting.ScriptEvaluatorFactory;
/**
* Base interface for Hibernate Validator specific configurations.
* Provides all Hibernate-specific configuration methods.
*
* @param <S> The actual type of the configuration
*/
interface BaseHibernateValidatorConfiguration<S extends BaseHibernateValidatorConfiguration<S>>
extends Configuration<S> {
// Configuration property constants
String FAIL_FAST = "hibernate.validator.fail_fast";
String ALLOW_PARAMETER_CONSTRAINT_OVERRIDE = "hibernate.validator.allow_parameter_constraint_override";
String ALLOW_MULTIPLE_CASCADED_VALIDATION_ON_RESULT = "hibernate.validator.allow_multiple_cascaded_validation_on_result";
String ALLOW_PARALLEL_METHODS_DEFINE_PARAMETER_CONSTRAINTS = "hibernate.validator.allow_parallel_method_parameter_constraint";
String CONSTRAINT_MAPPING_CONTRIBUTORS = "hibernate.validator.constraint_mapping_contributors";
String ENABLE_TRAVERSABLE_RESOLVER_RESULT_CACHE = "hibernate.validator.enable_traversable_resolver_result_cache";
String SCRIPT_EVALUATOR_FACTORY_CLASSNAME = "hibernate.validator.script_evaluator_factory";
String TEMPORAL_VALIDATION_TOLERANCE = "hibernate.validator.temporal_validation_tolerance";
String GETTER_PROPERTY_SELECTION_STRATEGY_CLASSNAME = "hibernate.validator.getter_property_selection_strategy";
String PROPERTY_NODE_NAME_PROVIDER_CLASSNAME = "hibernate.validator.property_node_name_provider";
String LOCALE_RESOLVER_CLASSNAME = "hibernate.validator.locale_resolver";
String CONSTRAINT_EXPRESSION_LANGUAGE_FEATURE_LEVEL = "hibernate.validator.constraint_expression_language_feature_level";
String CUSTOM_VIOLATION_EXPRESSION_LANGUAGE_FEATURE_LEVEL = "hibernate.validator.custom_violation_expression_language_feature_level";
String SHOW_VALIDATED_VALUE_IN_TRACE_LOGS = "hibernate.validator.show_validated_value_in_trace_logs";
String FAIL_FAST_ON_PROPERTY_VIOLATION = "hibernate.validator.fail_fast_on_property_violation";
/**
* Get the default ResourceBundleLocator for message interpolation.
* Retrieves the bundle "ValidationMessages" by default.
*
* @return the default ResourceBundleLocator, never null
*/
ResourceBundleLocator getDefaultResourceBundleLocator();
/**
* Create a new ConstraintMapping for programmatic constraint configuration.
* Must be added via addMapping() after configuration.
*
* @return new ConstraintMapping instance
*/
ConstraintMapping createConstraintMapping();
/**
* Get default ValueExtractor implementations per specification.
*
* @return default ValueExtractor implementations
* @since 6.0
*/
@Incubating
Set<jakarta.validation.valueextraction.ValueExtractor<?>> getDefaultValueExtractors();
/**
* Add programmatic constraint mapping to configuration.
*
* @param mapping constraint mapping to add
* @return this configuration for method chaining
*/
S addMapping(ConstraintMapping mapping);
/**
* Enable or disable fail-fast mode. When enabled, validation stops
* on the first constraint violation detected.
*
* @param failFast true to enable fail-fast, false otherwise
* @return this configuration for method chaining
*/
S failFast(boolean failFast);
/**
* Set class loader for loading user-provided resources including
* XML descriptors, classes specified in XML, and ValidationMessages bundle.
*
* @param externalClassLoader class loader for user resources
* @return this configuration for method chaining
* @since 5.2
*/
S externalClassLoader(ClassLoader externalClassLoader);
/**
* Control whether overriding methods can alter parameter constraints.
* Default is false (do not allow) per Jakarta Validation specification.
*
* @param allow true to allow parameter constraint override
* @return this configuration for method chaining
* @since 5.3
*/
S allowOverridingMethodAlterParameterConstraint(boolean allow);
/**
* Control whether multiple cascaded validation marks on return values
* are allowed in class hierarchy. Default is false (do not allow).
*
* @param allow true to allow multiple cascaded validation
* @return this configuration for method chaining
* @since 5.3
*/
S allowMultipleCascadedValidationOnReturnValues(boolean allow);
/**
* Control whether parallel methods can define parameter constraints.
* Default is false (do not allow) per Jakarta Validation specification.
*
* @param allow true to allow parallel method parameter constraints
* @return this configuration for method chaining
* @since 5.3
*/
S allowParallelMethodsDefineParameterConstraints(boolean allow);
/**
* Enable or disable per-validation-call caching of TraversableResolver results.
* Default is true (caching enabled).
*
* @param enabled true to enable caching
* @return this configuration for method chaining
* @since 6.0.3
*/
S enableTraversableResolverResultCache(boolean enabled);
/**
* Set custom ScriptEvaluatorFactory for script constraint evaluation.
*
* @param scriptEvaluatorFactory script evaluator factory
* @return this configuration for method chaining
* @since 6.0.3
*/
@Incubating
S scriptEvaluatorFactory(ScriptEvaluatorFactory scriptEvaluatorFactory);
/**
* Set acceptable margin of error for temporal constraint validation.
*
* @param temporalValidationTolerance tolerance duration
* @return this configuration for method chaining
* @since 6.0.5
*/
@Incubating
S temporalValidationTolerance(Duration temporalValidationTolerance);
/**
* Set payload passed to constraint validators. If called multiple times,
* only the last payload is propagated.
*
* @param constraintValidatorPayload payload for validators
* @return this configuration for method chaining
* @since 6.0.8
*/
@Incubating
S constraintValidatorPayload(Object constraintValidatorPayload);
/**
* Set getter property selection strategy for JavaBean getter detection.
*
* @param getterPropertySelectionStrategy strategy implementation
* @return this configuration for method chaining
* @since 6.1.0
*/
@Incubating
S getterPropertySelectionStrategy(GetterPropertySelectionStrategy getterPropertySelectionStrategy);
/**
* Set property node name provider for property path construction.
*
* @param propertyNodeNameProvider name provider implementation
* @return this configuration for method chaining
* @since 6.1.0
*/
@Incubating
S propertyNodeNameProvider(PropertyNodeNameProvider propertyNodeNameProvider);
/**
* Set supported locales for this ValidatorFactory.
* Can force initialization of resource bundles at bootstrap.
*
* @param locales set of supported locales
* @return this configuration for method chaining
* @since 6.1.1
*/
@Incubating
S locales(Set<Locale> locales);
/**
* Set supported locales for this ValidatorFactory (varargs version).
*
* @param locales supported locales
* @return this configuration for method chaining
* @since 6.1.1
*/
@Incubating
default S locales(Locale... locales) {
return locales(new java.util.HashSet<>(java.util.Arrays.asList(locales)));
}
/**
* Set default locale for constraint violation message interpolation.
*
* @param defaultLocale default locale
* @return this configuration for method chaining
* @since 6.1.1
*/
@Incubating
S defaultLocale(Locale defaultLocale);
/**
* Set locale resolver for dynamic locale resolution during message interpolation.
*
* @param localeResolver locale resolver implementation
* @return this configuration for method chaining
* @since 6.1.1
*/
@Incubating
S localeResolver(LocaleResolver localeResolver);
/**
* Set bean metadata class normalizer.
*
* @param beanMetaDataClassNormalizer normalizer implementation
* @return this configuration for method chaining
*/
@Incubating
S beanMetaDataClassNormalizer(BeanMetaDataClassNormalizer beanMetaDataClassNormalizer);
/**
* Set Expression Language feature level for constraint message interpolation.
* Controls which EL features are available for static constraint messages.
*
* @param expressionLanguageFeatureLevel feature level
* @return this configuration for method chaining
* @since 6.2
*/
@Incubating
S constraintExpressionLanguageFeatureLevel(ExpressionLanguageFeatureLevel expressionLanguageFeatureLevel);
/**
* Set Expression Language feature level for custom violation message interpolation.
* Controls which EL features are available for dynamic custom violations.
*
* @param expressionLanguageFeatureLevel feature level
* @return this configuration for method chaining
* @since 6.2
*/
@Incubating
S customViolationExpressionLanguageFeatureLevel(ExpressionLanguageFeatureLevel expressionLanguageFeatureLevel);
/**
* Enable or disable inclusion of validated values in trace logs.
* Default is false (values not printed) to protect sensitive data.
*
* @param enabled true to show values in trace logs
* @return this configuration for method chaining
* @since 8.0
*/
@Incubating
S showValidatedValuesInTraceLogs(boolean enabled);
/**
* Enable or disable skipping of class-level constraints when property-level
* constraints generate violations. When enabled, class-level validation
* is skipped if any property violation occurs.
*
* @param failFastOnPropertyViolation true to skip class-level constraints
* @return this configuration for method chaining
* @since 9.0
*/
@Incubating
S failFastOnPropertyViolation(boolean failFastOnPropertyViolation);
}Usage Example:
import jakarta.validation.Validation;
import jakarta.validation.ValidatorFactory;
import org.hibernate.validator.HibernateValidator;
import org.hibernate.validator.HibernateValidatorConfiguration;
import org.hibernate.validator.messageinterpolation.ExpressionLanguageFeatureLevel;
import java.time.Duration;
import java.util.Locale;
HibernateValidatorConfiguration configuration = Validation
.byProvider(HibernateValidator.class)
.configure();
configuration
.failFast(true)
.enableTraversableResolverResultCache(false)
.temporalValidationTolerance(Duration.ofMillis(100))
.constraintExpressionLanguageFeatureLevel(ExpressionLanguageFeatureLevel.BEAN_PROPERTIES)
.locales(Locale.US, Locale.UK, Locale.FRANCE)
.defaultLocale(Locale.US)
.showValidatedValuesInTraceLogs(false)
.failFastOnPropertyViolation(false);
ValidatorFactory factory = configuration.buildValidatorFactory();Primary configuration interface for standard Hibernate Validator usage with full-scope validation.
package org.hibernate.validator;
/**
* Uniquely identifies Hibernate Validator in Bean Validation bootstrap strategy.
* Contains Hibernate Validator specific configurations for standard usage.
* Extends Jakarta Validation Configuration with Hibernate-specific features.
*/
interface HibernateValidatorConfiguration
extends BaseHibernateValidatorConfiguration<HibernateValidatorConfiguration> {
// Inherits all methods from BaseHibernateValidatorConfiguration
}Extension of Jakarta Validation ValidatorFactory with Hibernate-specific features.
package org.hibernate.validator;
import jakarta.validation.ValidatorFactory;
import java.time.Duration;
import org.hibernate.validator.spi.nodenameprovider.PropertyNodeNameProvider;
import org.hibernate.validator.spi.properties.GetterPropertySelectionStrategy;
import org.hibernate.validator.spi.scripting.ScriptEvaluatorFactory;
/**
* Provides Hibernate Validator extensions to ValidatorFactory.
* Access Hibernate-specific factory methods and create Hibernate ValidatorContext.
*/
interface HibernateValidatorFactory extends ValidatorFactory {
/**
* Get ScriptEvaluatorFactory configured for this factory.
*
* @return script evaluator factory
*/
@Incubating
ScriptEvaluatorFactory getScriptEvaluatorFactory();
/**
* Get temporal validation tolerance configured for this factory.
*
* @return temporal validation tolerance
*/
@Incubating
Duration getTemporalValidationTolerance();
/**
* Get getter property selection strategy configured for this factory.
*
* @return getter property selection strategy
*/
@Incubating
GetterPropertySelectionStrategy getGetterPropertySelectionStrategy();
/**
* Get property node name provider configured for this factory.
*
* @return property node name provider
*/
@Incubating
PropertyNodeNameProvider getPropertyNodeNameProvider();
/**
* Create HibernateValidatorContext with Hibernate-specific configuration options.
*
* @return Hibernate validator context
*/
@Override
HibernateValidatorContext usingContext();
}Usage Example:
import org.hibernate.validator.HibernateValidatorFactory;
ValidatorFactory factory = // ... obtain factory
HibernateValidatorFactory hibernateFactory = factory.unwrap(HibernateValidatorFactory.class);
// Access Hibernate-specific features
Duration tolerance = hibernateFactory.getTemporalValidationTolerance();
ScriptEvaluatorFactory scriptFactory = hibernateFactory.getScriptEvaluatorFactory();
// Create Hibernate-specific validator context
HibernateValidatorContext context = hibernateFactory.usingContext();Per-validator configuration allowing runtime customization of validation behavior.
package org.hibernate.validator;
import jakarta.validation.ClockProvider;
import jakarta.validation.ConstraintValidatorFactory;
import jakarta.validation.MessageInterpolator;
import jakarta.validation.ParameterNameProvider;
import jakarta.validation.TraversableResolver;
import jakarta.validation.ValidatorContext;
import jakarta.validation.valueextraction.ValueExtractor;
import java.time.Duration;
/**
* Hibernate Validator specific context for creating Validator instances
* with additional configuration options beyond standard ValidatorContext.
*/
interface HibernateValidatorContext extends ValidatorContext {
/**
* Set message interpolator for this validator.
*
* @param messageInterpolator message interpolator instance
* @return this context for method chaining
*/
@Override
HibernateValidatorContext messageInterpolator(MessageInterpolator messageInterpolator);
/**
* Set traversable resolver for this validator.
*
* @param traversableResolver traversable resolver instance
* @return this context for method chaining
*/
@Override
HibernateValidatorContext traversableResolver(TraversableResolver traversableResolver);
/**
* Set constraint validator factory for this validator.
*
* @param factory constraint validator factory instance
* @return this context for method chaining
*/
@Override
HibernateValidatorContext constraintValidatorFactory(ConstraintValidatorFactory factory);
/**
* Set parameter name provider for this validator.
*
* @param parameterNameProvider parameter name provider instance
* @return this context for method chaining
* @since 5.2
*/
@Override
HibernateValidatorContext parameterNameProvider(ParameterNameProvider parameterNameProvider);
/**
* Set clock provider for this validator.
*
* @param clockProvider clock provider instance
* @return this context for method chaining
* @since 6.0
*/
@Override
HibernateValidatorContext clockProvider(ClockProvider clockProvider);
/**
* Add value extractor for this validator.
*
* @param extractor value extractor instance
* @return this context for method chaining
* @since 6.0
*/
@Override
HibernateValidatorContext addValueExtractor(ValueExtractor<?> extractor);
/**
* Enable or disable fail-fast mode for this validator.
* When enabled, validation stops on first violation.
*
* @param failFast true to enable fail-fast
* @return this context for method chaining
*/
HibernateValidatorContext failFast(boolean failFast);
/**
* Control whether overriding methods can alter parameter constraints.
*
* @param allow true to allow parameter constraint override
* @return this context for method chaining
* @since 5.3
*/
HibernateValidatorContext allowOverridingMethodAlterParameterConstraint(boolean allow);
/**
* Control whether multiple cascaded validation marks are allowed on return values.
*
* @param allow true to allow multiple cascaded validation
* @return this context for method chaining
* @since 5.3
*/
HibernateValidatorContext allowMultipleCascadedValidationOnReturnValues(boolean allow);
/**
* Control whether parallel methods can define parameter constraints.
*
* @param allow true to allow parallel method parameter constraints
* @return this context for method chaining
* @since 5.3
*/
HibernateValidatorContext allowParallelMethodsDefineParameterConstraints(boolean allow);
/**
* Enable or disable TraversableResolver result caching for this validator.
*
* @param enabled true to enable caching
* @return this context for method chaining
* @since 6.0.3
*/
HibernateValidatorContext enableTraversableResolverResultCache(boolean enabled);
/**
* Set temporal validation tolerance for this validator.
*
* @param temporalValidationTolerance tolerance duration
* @return this context for method chaining
* @since 6.0.5
*/
@Incubating
HibernateValidatorContext temporalValidationTolerance(Duration temporalValidationTolerance);
/**
* Set payload passed to constraint validators for this validator.
*
* @param constraintValidatorPayload payload object
* @return this context for method chaining
* @since 6.0.8
*/
@Incubating
HibernateValidatorContext constraintValidatorPayload(Object constraintValidatorPayload);
/**
* Control whether validated values appear in trace logs for this validator.
*
* @param enabled true to show values in trace logs
* @return this context for method chaining
* @since 8.0
*/
@Incubating
HibernateValidatorContext showValidatedValuesInTraceLogs(boolean enabled);
/**
* Enable or disable fail-fast on property violation for this validator.
*
* @param failFastOnPropertyViolation true to skip class-level constraints
* @return this context for method chaining
* @since 9.0
*/
@Incubating
HibernateValidatorContext failFastOnPropertyViolation(boolean failFastOnPropertyViolation);
}Usage Example:
import jakarta.validation.Validator;
import org.hibernate.validator.HibernateValidatorContext;
import java.time.Duration;
ValidatorFactory factory = // ... obtain factory
HibernateValidatorContext context = factory.unwrap(HibernateValidatorFactory.class)
.usingContext();
Validator validator = context
.failFast(true)
.temporalValidationTolerance(Duration.ofMillis(50))
.constraintValidatorPayload(new MyPayload())
.showValidatedValuesInTraceLogs(false)
.getValidator();Validation provider and configuration for predefined scope validation, allowing metadata collection at bootstrap time for performance optimization.
package org.hibernate.validator;
import jakarta.validation.spi.BootstrapState;
import jakarta.validation.spi.ValidationProvider;
import java.util.Set;
/**
* Implementation of ValidationProvider limiting validation to predefined scope.
* Allows metadata collection at bootstrap for build-time optimization.
*
* @since 6.1
*/
@Incubating
class PredefinedScopeHibernateValidator
implements ValidationProvider<PredefinedScopeHibernateValidatorConfiguration> {
PredefinedScopeHibernateValidatorConfiguration createSpecializedConfiguration(BootstrapState state);
jakarta.validation.Configuration<?> createGenericConfiguration(BootstrapState state);
jakarta.validation.ValidatorFactory buildValidatorFactory(jakarta.validation.spi.ConfigurationState configurationState);
}
/**
* Extension of HibernateValidatorConfiguration with methods for defining predefined scope.
* Allows specifying which built-in constraints, bean classes, and XML definitions to include.
*
* @since 6.1
*/
@Incubating
interface PredefinedScopeHibernateValidatorConfiguration
extends BaseHibernateValidatorConfiguration<PredefinedScopeHibernateValidatorConfiguration> {
/**
* Define set of built-in constraint annotation types to include in scope.
* Only specified constraints will be available for validation.
*
* @param constraints set of constraint class names (fully qualified)
* @return this configuration for method chaining
*/
@Incubating
PredefinedScopeHibernateValidatorConfiguration builtinConstraints(Set<String> constraints);
/**
* Define set of bean classes to initialize metadata for at bootstrap.
* Metadata for these classes will be prepared during factory creation.
*
* @param beanClasses set of bean classes
* @return this configuration for method chaining
*/
@Incubating
PredefinedScopeHibernateValidatorConfiguration initializeBeanMetaData(Set<Class<?>> beanClasses);
/**
* Control whether beans and constraints defined only in XML should be included.
*
* @param include true to include XML-only definitions
* @return this configuration for method chaining
*/
@Incubating
PredefinedScopeHibernateValidatorConfiguration includeBeansAndConstraintsDefinedOnlyInXml(boolean include);
}
/**
* Extension of HibernateValidatorFactory for predefined scope validation.
*
* @since 6.1
*/
@Incubating
interface PredefinedScopeHibernateValidatorFactory extends HibernateValidatorFactory {
// Inherits all methods from HibernateValidatorFactory
}Usage Example:
import jakarta.validation.Validation;
import jakarta.validation.ValidatorFactory;
import org.hibernate.validator.PredefinedScopeHibernateValidator;
import org.hibernate.validator.PredefinedScopeHibernateValidatorConfiguration;
import java.util.Set;
// Bootstrap with predefined scope
PredefinedScopeHibernateValidatorConfiguration configuration = Validation
.byProvider(PredefinedScopeHibernateValidator.class)
.configure();
configuration
// Only include specific built-in constraints
.builtinConstraints(Set.of(
"jakarta.validation.constraints.NotNull",
"jakarta.validation.constraints.Size",
"org.hibernate.validator.constraints.Length"
))
// Initialize metadata for specific bean classes at bootstrap
.initializeBeanMetaData(Set.of(User.class, Order.class, Product.class))
// Include XML-only definitions
.includeBeansAndConstraintsDefinedOnlyInXml(true);
ValidatorFactory factory = configuration.buildValidatorFactory();package org.hibernate.validator.metadata;
/**
* Defines how the validated class is normalized before being used as the key
* to retrieve bean metadata.
*
* In predefined scope validator factories, all classes that will be validated
* must be registered. To validate method calls, frameworks usually generate proxies
* to intercept calls. Such proxies might be hard to register as they are generated code.
*
* This contract allows normalizing the class before obtaining metadata from the
* PredefinedScopeBeanMetaDataManager, so only the original bean class needs to be
* registered, not the proxy class.
*
* This also avoids generating unnecessary metadata for proxy classes.
*
* @since 6.1
*/
@Incubating
interface BeanMetaDataClassNormalizer {
/**
* Normalizes the provided class as the key used to get bean metadata from
* the PredefinedScopeBeanMetaDataManager.
*
* @param beanClass the original bean class
* @param <T> the type of the bean
* @return the normalized class
*/
<T> Class<? super T> normalize(Class<T> beanClass);
}Usage Example:
import org.hibernate.validator.metadata.BeanMetaDataClassNormalizer;
import org.hibernate.validator.PredefinedScopeHibernateValidator;
import jakarta.validation.Validation;
// Custom normalizer that removes proxy suffixes
public class ProxyAwareBeanMetaDataClassNormalizer implements BeanMetaDataClassNormalizer {
@Override
public <T> Class<? super T> normalize(Class<T> beanClass) {
// If this is a CGLIB proxy, get the superclass
if (beanClass.getName().contains("$$EnhancerByCGLIB$$")) {
return beanClass.getSuperclass();
}
// If this is a Javassist proxy, get the superclass
if (beanClass.getName().contains("_$$_javassist")) {
return beanClass.getSuperclass();
}
// Otherwise return the class as-is
return beanClass;
}
}
// Configure with custom normalizer
ValidatorFactory factory = Validation
.byProvider(PredefinedScopeHibernateValidator.class)
.configure()
.beanMetaDataClassNormalizer(new ProxyAwareBeanMetaDataClassNormalizer())
.initializeBeanMetaData(Set.of(User.class, Order.class))
.buildValidatorFactory();
// Now validation will work even with proxy instances
User userProxy = createProxiedUser(); // Returns User$$EnhancerByCGLIB$$abc123
validator.validate(userProxy); // Uses User.class metadata (not proxy class)Install with Tessl CLI
npx tessl i tessl/maven-org-hibernate-validator--hibernate-validator