ADi3ek
ADi3ek

Reputation: 675

@Query annotation and named parameters in quoted strings

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

Answers (1)

ADi3ek
ADi3ek

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

Related Questions