I upgraded my codebase from Grails 2.1.0 to 3.2.0. However, I encountered a situation that one of my queries did not work as expected.
public List<Location> findAllLocationsByNames(Collection<String> placeNames) {
return Location.executeQuery("select l from Location l where l.placeName in (:placeNames)", [placeNames: placeNames])
}
Before upgrade, this query was working well. I passed in a collection of type LinkedKeySet
(from HashMap.getKeySet()
) and it returns correctly the list of locations. But now with new version of Grails I got this error:
java.util.LinkedHashMap$LinkedKeySet cannot be cast to java.lang.String
I digged a bit deeper inside Grails and GORM and saw that QueryTranslatorImpl translated the named parameter placeNames
to SQL AST as [NAMED_PARAM] ParameterNode: '?' {name=placeNames, expectedType=org.hibernate.type.StringType@49c72fb7}
, but I'm not sure why.
In the end, I changed the original query to use where
and DetachedCriteria:
public List<Location> findAllLocationsByNames(Collection<String> placeNames) {
return Location.where {placeName in placeNames}.list()
}
This time, everything works fine and the returned result was what I expected.
What is the problem with the first query using executeQuery
?
Seems newer versions of Hibernate are less lenient if you specify parameters that are not of type java.util.List
and instead are other collection types (Set
etc.)