Scope of ConstraintDescriptors sometimes wrong in type hierarchies
------------------------------------------------------------------
Key: HV-443
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HV-443
Project: Hibernate Validator
Issue Type: Bug
Components: engine
Affects Versions: 4.1.0.Final
Reporter: Gunnar Morling
Fix For: 4.3.0.next
Using the BV meta data API it is possible to retrieve meta information on the constraints
of given Java types. Using the {{ConstraintFinder}} API the scope of the constraints to
retrieve meta data for can be restricted.
Due to the caching of meta data in {{BeanMetaDataCache}} it can happen under certain
circumstances that constraints are declared in scope {{LOCAL_ELEMENT}}, although it should
be {{HIERARCHY}} instead.
The following test demonstrates the bug:
{code:java}
public class CacheTest {
@Test
public void constraintsFromSuperTypeAreInLocalScopeWhenSuperTypeIsLoadedFromCache() {
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
// loads BeanMetaData for A and puts it into the BeanMetaDataCache
PropertyDescriptor propertyDescriptorForSuperType = validator
.getConstraintsForClass(A.class).getConstraintsForProperty("foo");
Set<ConstraintDescriptor<?>> constraintDescriptorsFromSuperType =
propertyDescriptorForSuperType
.findConstraints().lookingAt(Scope.LOCAL_ELEMENT)
.getConstraintDescriptors();
assertEquals(constraintDescriptorsFromSuperType.size(), 1);
// re-uses BeanMetaData for A from cache, keeps A's constraints in
// LOCAL_ELEMENT scope
PropertyDescriptor propertyDescriptorForSubType = validator
.getConstraintsForClass(B.class).getConstraintsForProperty("foo");
Set<ConstraintDescriptor<?>> constraintDescriptorsFromSubType =
propertyDescriptorForSubType
.findConstraints().lookingAt(Scope.LOCAL_ELEMENT)
.getConstraintDescriptors();
// fails
assertEquals(constraintDescriptorsFromSubType.size(), 0, "No descriptor in LOCAL
scope expected for B.foo");
}
@Test
public void
constraintsFromSuperTypeAreInHierarchyScopeWhenSuperTypeIsNotLoadedFromCache() {
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
// loads BeanMetaData for A when traversing B's hierarchy, A's constraints
// are correctly in HIERARCHY scope
PropertyDescriptor propertyDescriptorForSubType = validator
.getConstraintsForClass(B.class).getConstraintsForProperty("foo");
Set<ConstraintDescriptor<?>> constraintDescriptorsFromSubType =
propertyDescriptorForSubType
.findConstraints().lookingAt(Scope.LOCAL_ELEMENT)
.getConstraintDescriptors();
assertEquals(constraintDescriptorsFromSubType.size(), 0, "No descriptor in LOCAL
scope expected for B.foo");
constraintDescriptorsFromSubType = propertyDescriptorForSubType
.findConstraints().lookingAt(Scope.HIERARCHY)
.getConstraintDescriptors();
assertEquals(constraintDescriptorsFromSubType.size(), 1, "One descriptor in
HIERARCHY scope expected for B.foo");
}
public static class A {
@NotNull
public String getFoo() {
return null;
}
}
public static class B extends A {
}
}
{code}
The bug is caused by retrieving the meta data for {{A}} from the cache when building the
meta data for its sub-type {{B}} (see
{{constraintsFromSuperTypeAreInLocalScopeWhenSuperTypeIsLoadedFromCache}}). In this case
the constraint from {{A}} are added to {{B}} but remain in scope {{LOCAL_ELEMENT}}.
The bug does not occur when the meta data for {{A}} is retrieved when traversing the type
hierarchy while building up the meta data for {{B}} (see
{{constraintsFromSuperTypeAreInHierarchyScopeWhenSuperTypeIsNotLoadedFromCache}}), though
I guess the constraints would be wrongly in scope {{HIERARCHY}} if afterwards the
descriptors for {{A}} itself would be retrieved.
To fix this bug the constraint scope needs to be re-determined always if the meta data is
retrieved from the cache.
--
This message is automatically generated by JIRA.
For more information on JIRA, see: