[
http://opensource.atlassian.com/projects/hibernate/browse/HV-466?page=com...
]
Hardy Ferentschik commented on HV-466:
--------------------------------------
I think this:
{code}
private <T, U, V, E extends ConstraintViolation<T>> void
validateConstraintsForDefaultGroup(ValidationContext<T, E> validationContext,
ValueContext<U, V> valueContext) {
BeanMetaData<U> beanMetaData = getBeanMetaData( valueContext.getCurrentBeanType()
);
Set<Class> processedInterfaces = newHashSet();
// evaluating the constraints of a bean per class in hierarchy, this is necessary to
detect potential default group re-definitions
for ( Class<?> clazz : beanMetaData.getClassHierarchy() ) {
BeanMetaData<U> hostingBeanMetaData = (BeanMetaData<U>) getBeanMetaData(
clazz );
boolean defaultGroupSequenceIsRedefined =
hostingBeanMetaData.defaultGroupSequenceIsRedefined();
List<Class<?>> defaultGroupSequence =
hostingBeanMetaData.getDefaultGroupSequence( valueContext.getCurrentBean() );
Set<BeanMetaConstraint<? extends Annotation>> metaConstraints =
hostingBeanMetaData.getDirectMetaConstraints();
// if the current class redefined the default group sequence, this sequence has to be
applied to all the class hierarchy.
if ( defaultGroupSequenceIsRedefined ) {
metaConstraints = hostingBeanMetaData.getMetaConstraints();
}
PathImpl currentPath = valueContext.getPropertyPath();
for ( Class<?> defaultSequenceMember : defaultGroupSequence ) {
valueContext.setCurrentGroup( defaultSequenceMember );
boolean validationSuccessful = true;
for ( BeanMetaConstraint<? extends Annotation> metaConstraint : metaConstraints
) {
if ( metaConstraint.getLocation().getBeanClass().isInterface() &&
processedInterfaces.contains( metaConstraint.getLocation().getBeanClass() ) ) {
continue;
}
else {
processedInterfaces.add( metaConstraint.getLocation().getClass() );
}
boolean tmp = validateConstraint(
validationContext, valueContext, metaConstraint
);
if ( validationContext.shouldFailFast() ) {
return;
}
validationSuccessful = validationSuccessful && tmp;
// reset the path
valueContext.setPropertyPath( currentPath );
validationContext.markProcessed(
valueContext.getCurrentBean(),
valueContext.getCurrentGroup(),
valueContext.getPropertyPath()
);
}
if ( !validationSuccessful ) {
break;
}
}
// all constraints in the hierarchy has been validated, stop validation.
if ( defaultGroupSequenceIsRedefined ) {
break;
}
}
}
{code}
would already work. Only evaluate an interface once at the "lowest" possible
level. Say you have an instance of _C_. It is really for this instance you have to
evaluate the interfaces of _A_. We are not evaluating an instance of _C_ and an instance
of _B_. The validated entity entity implements the interface only once.
Avoid repeated validation of constraints in certain type hierarchies
--------------------------------------------------------------------
Key: HV-466
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HV-466
Project: Hibernate Validator
Issue Type: Bug
Components: engine
Reporter: Gunnar Morling
Priority: Minor
Fix For: 4.x
Let there be the following type hierarchy where the same interface is implemented by two
types in an inheritance hierarchy:
{code:java}
public interface A {
@NotNull
String getA();
}
public class B implements A {
public String getA() {
return null;
}
}
public class C extends B implements A {
}
{code}
When validating an instance of {{C}} the {{@NotNull}} constraint on {{A#getA()}} is
evaluated twice when traversing the type hierarchy of {{C}} in {{ValidatorImpl}}.
This seems to be against the BV spec. which says in chapter 3.5:
{quote}
Note that this [algorithm] implies that a given validation constraint will not be
processed more than once per validation.
{quote}
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira