[hibernate-issues] [Hibernate-JIRA] Commented: (HV-466) Avoid repeated validation of constraints in certain type hierarchies

Hardy Ferentschik (JIRA) noreply at atlassian.com
Wed Apr 20 04:53:59 EDT 2011


    [ http://opensource.atlassian.com/projects/hibernate/browse/HV-466?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=42115#action_42115 ] 

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.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the hibernate-issues mailing list