Skip to content

Commit 67c6175

Browse files
committed
HV-1589 Include the initialization context in all the caching mechanisms
1 parent 4186c93 commit 67c6175

File tree

7 files changed

+128
-47
lines changed

7 files changed

+128
-47
lines changed

engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorFactoryImpl.java

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,11 @@
3434
import org.hibernate.validator.HibernateValidatorContext;
3535
import org.hibernate.validator.HibernateValidatorFactory;
3636
import org.hibernate.validator.cfg.ConstraintMapping;
37+
import org.hibernate.validator.constraintvalidation.HibernateConstraintValidatorInitializationContext;
3738
import org.hibernate.validator.internal.cfg.context.DefaultConstraintMapping;
3839
import org.hibernate.validator.internal.engine.constraintdefinition.ConstraintDefinitionContribution;
3940
import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager;
41+
import org.hibernate.validator.internal.engine.constraintvalidation.HibernateConstraintValidatorInitializationContextImpl;
4042
import org.hibernate.validator.internal.engine.groups.ValidationOrderGenerator;
4143
import org.hibernate.validator.internal.engine.scripting.DefaultScriptEvaluatorFactory;
4244
import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager;
@@ -177,8 +179,6 @@ public ValidatorFactoryImpl(ConfigurationState configurationState) {
177179
getAllowParallelMethodsDefineParameterConstraints( hibernateSpecificConfig, properties )
178180
).build();
179181

180-
this.constraintValidatorManager = new ConstraintValidatorManager( configurationState.getConstraintValidatorFactory() );
181-
182182
this.validatorFactoryScopedContext = new ValidatorFactoryScopedContext(
183183
configurationState.getMessageInterpolator(),
184184
configurationState.getTraversableResolver(),
@@ -191,6 +191,11 @@ public ValidatorFactoryImpl(ConfigurationState configurationState) {
191191
getConstraintValidatorPayload( hibernateSpecificConfig )
192192
);
193193

194+
this.constraintValidatorManager = new ConstraintValidatorManager(
195+
configurationState.getConstraintValidatorFactory(),
196+
this.validatorFactoryScopedContext.getConstraintValidatorInitializationContext()
197+
);
198+
194199
this.validationOrderGenerator = new ValidationOrderGenerator();
195200

196201
if ( LOG.isDebugEnabled() ) {
@@ -702,8 +707,16 @@ static class ValidatorFactoryScopedContext {
702707
*/
703708
private final boolean traversableResolverResultCacheEnabled;
704709

710+
/**
711+
* The constraint validator payload.
712+
*/
705713
private final Object constraintValidatorPayload;
706714

715+
/**
716+
* The constraint validator initialization context.
717+
*/
718+
private final HibernateConstraintValidatorInitializationContextImpl constraintValidatorInitializationContext;
719+
707720
private ValidatorFactoryScopedContext(MessageInterpolator messageInterpolator,
708721
TraversableResolver traversableResolver,
709722
ExecutableParameterNameProvider parameterNameProvider,
@@ -713,6 +726,22 @@ private ValidatorFactoryScopedContext(MessageInterpolator messageInterpolator,
713726
boolean failFast,
714727
boolean traversableResolverResultCacheEnabled,
715728
Object constraintValidatorPayload) {
729+
this( messageInterpolator, traversableResolver, parameterNameProvider, clockProvider, temporalValidationTolerance, scriptEvaluatorFactory, failFast,
730+
traversableResolverResultCacheEnabled, constraintValidatorPayload,
731+
new HibernateConstraintValidatorInitializationContextImpl( scriptEvaluatorFactory, clockProvider,
732+
temporalValidationTolerance, constraintValidatorPayload ) );
733+
}
734+
735+
private ValidatorFactoryScopedContext(MessageInterpolator messageInterpolator,
736+
TraversableResolver traversableResolver,
737+
ExecutableParameterNameProvider parameterNameProvider,
738+
ClockProvider clockProvider,
739+
Duration temporalValidationTolerance,
740+
ScriptEvaluatorFactory scriptEvaluatorFactory,
741+
boolean failFast,
742+
boolean traversableResolverResultCacheEnabled,
743+
Object constraintValidatorPayload,
744+
HibernateConstraintValidatorInitializationContextImpl constraintValidatorInitializationContext) {
716745
this.messageInterpolator = messageInterpolator;
717746
this.traversableResolver = traversableResolver;
718747
this.parameterNameProvider = parameterNameProvider;
@@ -722,6 +751,7 @@ private ValidatorFactoryScopedContext(MessageInterpolator messageInterpolator,
722751
this.failFast = failFast;
723752
this.traversableResolverResultCacheEnabled = traversableResolverResultCacheEnabled;
724753
this.constraintValidatorPayload = constraintValidatorPayload;
754+
this.constraintValidatorInitializationContext = constraintValidatorInitializationContext;
725755
}
726756

727757
public MessageInterpolator getMessageInterpolator() {
@@ -760,6 +790,10 @@ public Object getConstraintValidatorPayload() {
760790
return this.constraintValidatorPayload;
761791
}
762792

793+
public HibernateConstraintValidatorInitializationContext getConstraintValidatorInitializationContext() {
794+
return this.constraintValidatorInitializationContext;
795+
}
796+
763797
static class Builder {
764798
private final ValidatorFactoryScopedContext defaultContext;
765799

@@ -772,6 +806,7 @@ static class Builder {
772806
private boolean failFast;
773807
private boolean traversableResolverResultCacheEnabled;
774808
private Object constraintValidatorPayload;
809+
private HibernateConstraintValidatorInitializationContextImpl constraintValidatorInitializationContext;
775810

776811
Builder(ValidatorFactoryScopedContext defaultContext) {
777812
Contracts.assertNotNull( defaultContext, "Default context cannot be null." );
@@ -786,6 +821,7 @@ static class Builder {
786821
this.failFast = defaultContext.failFast;
787822
this.traversableResolverResultCacheEnabled = defaultContext.traversableResolverResultCacheEnabled;
788823
this.constraintValidatorPayload = defaultContext.constraintValidatorPayload;
824+
this.constraintValidatorInitializationContext = defaultContext.constraintValidatorInitializationContext;
789825
}
790826

791827
public Builder setMessageInterpolator(MessageInterpolator messageInterpolator) {
@@ -874,7 +910,14 @@ public ValidatorFactoryScopedContext build() {
874910
scriptEvaluatorFactory,
875911
failFast,
876912
traversableResolverResultCacheEnabled,
877-
constraintValidatorPayload
913+
constraintValidatorPayload,
914+
HibernateConstraintValidatorInitializationContextImpl.of(
915+
constraintValidatorInitializationContext,
916+
scriptEvaluatorFactory,
917+
clockProvider,
918+
temporalValidationTolerance,
919+
constraintValidatorPayload
920+
)
878921
);
879922
}
880923
}

engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
import org.hibernate.validator.internal.engine.ValidationContext.ValidatorScopedContext;
4141
import org.hibernate.validator.internal.engine.ValidatorFactoryImpl.ValidatorFactoryScopedContext;
4242
import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager;
43-
import org.hibernate.validator.internal.engine.constraintvalidation.HibernateConstraintValidatorInitializationContextImpl;
4443
import org.hibernate.validator.internal.engine.groups.Group;
4544
import org.hibernate.validator.internal.engine.groups.GroupWithInheritance;
4645
import org.hibernate.validator.internal.engine.groups.Sequence;
@@ -145,9 +144,7 @@ public ValidatorImpl(ConstraintValidatorFactory constraintValidatorFactory,
145144
this.validationOrderGenerator = validationOrderGenerator;
146145
this.validatorScopedContext = new ValidatorScopedContext( validatorFactoryScopedContext );
147146
this.traversableResolver = validatorFactoryScopedContext.getTraversableResolver();
148-
this.constraintValidatorInitializationContext = new HibernateConstraintValidatorInitializationContextImpl(
149-
validatorScopedContext.getScriptEvaluatorFactory(), validatorScopedContext.getClockProvider(),
150-
validatorScopedContext.getTemporalValidationTolerance(), validatorScopedContext.getConstraintValidatorPayload() );
147+
this.constraintValidatorInitializationContext = validatorFactoryScopedContext.getConstraintValidatorInitializationContext();
151148
}
152149

153150
@Override

engine/src/main/java/org/hibernate/validator/internal/engine/constraintvalidation/ConstraintTree.java

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import javax.validation.ConstraintViolation;
2121
import javax.validation.ValidationException;
2222

23-
import org.hibernate.validator.constraintvalidation.HibernateConstraintValidator;
2423
import org.hibernate.validator.internal.engine.ValidationContext;
2524
import org.hibernate.validator.internal.engine.ValueContext;
2625
import org.hibernate.validator.internal.metadata.descriptor.ConstraintDescriptorImpl;
@@ -53,7 +52,7 @@ public abstract class ConstraintTree<A extends Annotation> {
5352
* Either the initialized constraint validator for the default constraint validator factory or
5453
* {@link ConstraintValidatorManager#DUMMY_CONSTRAINT_VALIDATOR}.
5554
*/
56-
private volatile ConstraintValidator<A, ?> constraintValidatorForDefaultConstraintValidatorFactory;
55+
private volatile ConstraintValidator<A, ?> constraintValidatorForDefaultConstraintValidatorFactoryAndInitializationContext;
5756

5857
protected ConstraintTree(ConstraintDescriptorImpl<A> descriptor, Type validatedValueType) {
5958
this.descriptor = descriptor;
@@ -113,21 +112,18 @@ private ValidationException getExceptionForNullValidator(Type validatedValueType
113112
protected final <T> ConstraintValidator<A, ?> getInitializedConstraintValidator(ValidationContext<T> validationContext, ValueContext<?, ?> valueContext) {
114113
ConstraintValidator<A, ?> validator;
115114

116-
if ( validationContext.getConstraintValidatorFactory() == validationContext.getConstraintValidatorManager().getDefaultConstraintValidatorFactory() ) {
117-
validator = constraintValidatorForDefaultConstraintValidatorFactory;
115+
if ( validationContext.getConstraintValidatorFactory() == validationContext.getConstraintValidatorManager().getDefaultConstraintValidatorFactory()
116+
&& validationContext.getConstraintValidatorInitializationContext() == validationContext.getConstraintValidatorManager()
117+
.getDefaultConstraintValidatorInitializationContext() ) {
118+
validator = constraintValidatorForDefaultConstraintValidatorFactoryAndInitializationContext;
118119

119120
if ( validator == null ) {
120121
synchronized ( this ) {
121-
validator = constraintValidatorForDefaultConstraintValidatorFactory;
122+
validator = constraintValidatorForDefaultConstraintValidatorFactoryAndInitializationContext;
122123
if ( validator == null ) {
123124
validator = getInitializedConstraintValidator( validationContext );
124125

125-
// HibernateConstraintValidator instances should not be cached within this constraint tree instance, only ConstraintValidatorManager
126-
// should handle their caching. That's because the HibernateConstraintValidatorInitializationContext influences their caching behaviour.
127-
// (HibernateConstraintValidatorInitializationContext could have changed during a ValidatorFactory lifetime - via usingContext())
128-
if ( !( validator instanceof HibernateConstraintValidator ) ) {
129-
constraintValidatorForDefaultConstraintValidatorFactory = validator;
130-
}
126+
constraintValidatorForDefaultConstraintValidatorFactoryAndInitializationContext = validator;
131127
}
132128
}
133129
}

0 commit comments

Comments
 (0)