spring-projects / spring-data-commons

Spring Data Commons. Interfaces and code shared between the various datastore specific implementations.
https://spring.io/projects/spring-data
Apache License 2.0
757 stars 660 forks source link

QueryDSL web support: unable to customize Map properties [DATACMNS-1525] #1921

Open spring-projects-issues opened 5 years ago

spring-projects-issues commented 5 years ago

Geert Graat opened DATACMNS-1525 and commented

I am using QueryDSL web support and currently customizing it as per the documentation. I run into a problem with properties of type Map. Below is a snippet from my generated QITask class:

public final MapPath<String, String, StringPath> customFields = this.<String, String, StringPath>createMap("customFields", String.class, String.class, StringPath.class);

When I want to customize this property, I use the following

bindings.bind(task.customFields).first((path, values) -> ...

**

The problem is that because task.customFields is defined as a MapPath, the values parameter is inferred to be a Map. But when I run this, it always contains a List.

When I debugged the QuerydslPredicateBuilder.getPredicate(..) method, and the convertToPropertyPathSpecificType(..) method was called, I found that there is no Converter available in the default ConversionService in Spring to convert from String (which the query argument always is) and Map. Therefore the query arguments are simply returned in List. 

As a workaround, I registered my own Converter that splits the query argument string on a specific character and creates a Map with the first part as key and the second part as value. So with this, I can execute queries like:

http://...query?customFields=key:value

Affects: 2.1.6 (Lovelace SR6)

spring-projects-issues commented 5 years ago

Oliver Drotbohm commented

As you already found out, this is currently not supported, mostly because unless I oversee something there's no formally specified way of transferring map data via a URI. We're not eager to create a Sprign Data specific flavor for that

spring-projects-issues commented 5 years ago

Geert Graat commented

I understand that Spring Data cannot support conversion of URI data to a Map as there is no universal way of doing that. But right now, if you do use a Map in your QueryDsl object and want to customize its binding, the code breaks as a Map is expected but a List is available. Shouldn't this be changed then so that a MapPath is inferred to expect a List of values instead of a Map of values? In that way, you still need to convert the List contents to a Map, but that is exactly what you want to do because you can use your own conventions, however you can do this when customizing the binding, which seems the appropriate place for me