Reputation: 675
So, here is the native MySQL query where I want to get all the rows based on JSON key-value pairs (ev_data is json type column), and it works just fine:
SELECT * FROM event WHERE JSON_CONTAINS(ev_data, '{"key":"key1","value":"val1"}','$.items')
An example of ev_data
column content:
{"items":[{"key":"key1","value":"val1"},{"key":"key2","value":"val2"}]}
Now, I am using Spring Boot's CrudRepository
interface and @Query
annotation for my custom fetch method as follows:
@Query(value="SELECT * FROM event WHERE JSON_CONTAINS(ev_data, '{\"key\" : \"key1\", \"value\" : :value}', '$.items')", nativeQuery=true)
Set<Event> findAllByItemKey1Value(@Param("value") String value);
This, however, won't work and trigger an exception like:
java.lang.IllegalArgumentException: Parameter with that name [value] did not exist
because, apparently, you are not allowed to use parameters (named or indexed) inside quoted strings. Not sure if it's JPA/JPQL or Spring Boot thing but it is a fact.
Upvotes: 1
Views: 1256
Reputation: 675
The only workaround solution I have found so far is by using MySQL string REPLACE()
function:
@Query(value="SELECT * FROM event WHERE JSON_CONTAINS(ev_data, REPLACE('{\"key\" : \"key1\", \"value\" : \"*v*\"}','*v*', :value), '$.items')", nativeQuery=true)
Set<Event> findAllByItemKey1Value(@Param("value") String value);
It's not very elegant but it works for me and similar trick should also work for any named parameters used inside quotes.
Anyway, please let me know if you think this can be done better or more kosher, so to speak ;-)
Upvotes: 3