3232import org .springframework .data .mapping .PropertyPath ;
3333import org .springframework .data .querydsl .EntityPathResolver ;
3434import org .springframework .data .util .TypeInformation ;
35+ import org .springframework .lang .Nullable ;
3536import org .springframework .util .Assert ;
37+ import org .springframework .util .ClassUtils ;
3638import org .springframework .util .MultiValueMap ;
37- import org .springframework .util .StringUtils ;
39+ import org .springframework .util .ObjectUtils ;
3840
3941import com .querydsl .core .BooleanBuilder ;
4042import com .querydsl .core .types .Path ;
@@ -81,8 +83,7 @@ public QuerydslPredicateBuilder(ConversionService conversionService, EntityPathR
8183 * @param bindings the {@link QuerydslBindings} for the predicate.
8284 * @return the {@link Predicate}.
8385 */
84- public Predicate getPredicate (TypeInformation <?> type , MultiValueMap <String , String > values ,
85- QuerydslBindings bindings ) {
86+ public Predicate getPredicate (TypeInformation <?> type , MultiValueMap <String , ?> values , QuerydslBindings bindings ) {
8687
8788 Assert .notNull (bindings , "Context must not be null!" );
8889
@@ -92,9 +93,9 @@ public Predicate getPredicate(TypeInformation<?> type, MultiValueMap<String, Str
9293 return getPredicate (builder );
9394 }
9495
95- for (Entry <String , List <String >> entry : values .entrySet ()) {
96+ for (Entry <String , ? extends List <? >> entry : values .entrySet ()) {
9697
97- if (isSingleElementCollectionWithoutText (entry .getValue ())) {
98+ if (isSingleElementCollectionWithEmptyItem (entry .getValue ())) {
9899 continue ;
99100 }
100101
@@ -165,33 +166,44 @@ private Path<?> getPath(PathInformation path, QuerydslBindings bindings) {
165166
166167 /**
167168 * Converts the given source values into a collection of elements that are of the given {@link PropertyPath}'s type.
168- * Considers a single element list with an empty {@link String} an empty collection because this basically indicates
169- * the property having been submitted but no value provided.
169+ * Considers a single element list with an empty object an empty collection because this basically indicates the
170+ * property having been submitted but no value provided.
170171 *
171172 * @param source must not be {@literal null}.
172173 * @param path must not be {@literal null}.
173174 * @return
174175 */
175- private Collection <Object > convertToPropertyPathSpecificType (List <String > source , PathInformation path ) {
176+ private Collection <Object > convertToPropertyPathSpecificType (List <? > source , PathInformation path ) {
176177
177178 Class <?> targetType = path .getLeafType ();
178179
179- if (source .isEmpty () || isSingleElementCollectionWithoutText (source )) {
180+ if (source .isEmpty () || isSingleElementCollectionWithEmptyItem (source )) {
180181 return Collections .emptyList ();
181182 }
182183
183184 Collection <Object > target = new ArrayList <>(source .size ());
184185
185- for (String value : source ) {
186-
187- target .add (conversionService .canConvert (String .class , targetType )
188- ? conversionService .convert (value , TypeDescriptor .forObject (value ), getTargetTypeDescriptor (path ))
189- : value );
186+ for (Object value : source ) {
187+ target .add (getValue (path , targetType , value ));
190188 }
191189
192190 return target ;
193191 }
194192
193+ @ Nullable
194+ private Object getValue (PathInformation path , Class <?> targetType , Object value ) {
195+
196+ if (ClassUtils .isAssignableValue (targetType , value )) {
197+ return value ;
198+ }
199+
200+ if (conversionService .canConvert (value .getClass (), targetType )) {
201+ return conversionService .convert (value , TypeDescriptor .forObject (value ), getTargetTypeDescriptor (path ));
202+ }
203+
204+ return value ;
205+ }
206+
195207 /**
196208 * Returns the target {@link TypeDescriptor} for the given {@link PathInformation} by either inspecting the field or
197209 * property (the latter preferred) to pick up annotations potentially defined for formatting purposes.
@@ -213,21 +225,21 @@ private static TypeDescriptor getTargetTypeDescriptor(PathInformation path) {
213225 .nested (new Property (owningType , descriptor .getReadMethod (), descriptor .getWriteMethod (), leafProperty ), 0 );
214226
215227 if (result == null ) {
216- throw new IllegalStateException (String .format ("Could not obtain TypeDesciptor for PathInformation %s!" , path ));
228+ throw new IllegalStateException (String .format ("Could not obtain TypeDescriptor for PathInformation %s!" , path ));
217229 }
218230
219231 return result ;
220232 }
221233
222234 /**
223- * Returns whether the given collection has exactly one element that doesn't contain any text. This is basically an
224- * indicator that a request parameter has been submitted but no value for it.
235+ * Returns whether the given collection has exactly one element that is empty (i.e. doesn't contain text) . This is
236+ * basically an indicator that a request parameter has been submitted but no value for it.
225237 *
226238 * @param source must not be {@literal null}.
227239 * @return
228240 */
229- private static boolean isSingleElementCollectionWithoutText (List <String > source ) {
230- return source .size () == 1 && ! StringUtils . hasLength (source .get (0 ));
241+ private static boolean isSingleElementCollectionWithEmptyItem (List <? > source ) {
242+ return source .size () == 1 && ObjectUtils . isEmpty (source .get (0 ));
231243 }
232244
233245 /**
0 commit comments