Skip to content

QuerydslPredicateArgumentResolver does not handle annotations in a spring-like way [DATACMNS-1334] #1772

Open
@spring-projects-issues

Description

@spring-projects-issues

George Hartz opened DATACMNS-1334 and commented

The QuerydslPredicateArgumentResolver class does not handle searching for @QuerydslPredicate annotations in the same way most Spring annotation searching happens – specifically it doesn't appear to find them when defined on an interface, but rather just the concrete method. Additionally, the annotation metadata implies it can be placed on a type (and it can) but it isn't used in that case. 

 

Our specific use case that ran into this is the use of a method on a generic-typed base class that takes a Predicate parameter. The find method's return type is the generic type, but because of erasure, is actually Object at runtime. The Querydsl support attempts to load a QObject type for the Predicate, which does't exist. 

 

One would assume that annotating the class would provide a fall-back type for those scenarios, or a @QuerydslPredicate annotation on an interface declaration that the base class is implementing would be picked up, but neither are true.

 

I'm not set up to be able to submit a patch for this, because we don't want to be running a custom Spring build. The way we fixed it was to not register the QuerydslPredicateArgumentResolver class, and to register a version with the extractTypeInfo method reimplemented as such:

static TypeInformation<?> extractTypeInfo(MethodParameter parameter) {

		Optional<QuerydslPredicate> annotation = Optional
				.ofNullable(AnnotationUtils.findAnnotation(parameter.getMethod(), QuerydslPredicate.class));
		
		if (!annotation.isPresent())
			annotation = Optional
					.ofNullable(AnnotationUtils.findAnnotation(parameter.getContainingClass(), QuerydslPredicate.class));
		
		return annotation.filter(it -> !Object.class.equals(it.root()))//
				.<TypeInformation<?>> map(it -> ClassTypeInformation.from(it.root()))//
				.orElseGet(() -> detectDomainType(parameter));
	}

 

 Using AnnotationUtils means the "normal" spring logic of finding annotations is used, and we added a fall-back to look on the type hierarchy for the annotation, if one wasn't found. Only after that does the return type get used. 


Affects: 2.0.7 (Kay SR7)

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions