-
Notifications
You must be signed in to change notification settings - Fork 101
Description
When using the autocomplete feature with both .withScore() and .withPayload() options enabled, a ClassCastException occurs. The application throws an error indicating that redis.clients.jedis.resps.Tuple cannot be cast to java.lang.String.
Steps to Reproduce (Example from the docs)
- Create an entity with
@AutoCompleteand@AutoCompletePayloadannotations:
@Document
public class Airport {
@Id
private String id;
@AutoComplete
private String name;
@AutoCompletePayload("name") // Links to the "name" autocomplete field
private String code;
@AutoCompletePayload("name")
private String city;
@AutoCompletePayload("name")
private String country;
}- Use autocomplete with both score and payload options:
AutoCompleteOptions options = AutoCompleteOptions.get()
.fuzzy() // Enable fuzzy matching
.withScore() // Include relevance scores
.withPayload() // Include payload data
.limit(10); // Limit to 10 results
List<Suggestion> suggestions = airportRepository.autoCompleteName("john f k", options);Expected Behavior
The autocomplete should return suggestions with both score and payload data.
Actual Behavior
The following exception is thrown:
java.lang.ClassCastException: class redis.clients.jedis.resps.Tuple cannot be cast to class java.lang.String
at org.springframework.data.redis.serializer.StringRedisSerializer.serialize(StringRedisSerializer.java:36)
at org.springframework.data.redis.core.AbstractOperations.rawHashKey(AbstractOperations.java:187)
at org.springframework.data.redis.core.DefaultHashOperations.get(DefaultHashOperations.java:58)
at com.redis.om.spring.ops.search.SearchOperationsImpl.lambda$getSuggestion$0(SearchOperationsImpl.java:138)Root Cause Analysis
In SearchOperationsImpl.java, when both withScore() and withPayload() are enabled, the code receives suggestions as List<Tuple> objects. However, on line 138, it incorrectly passes the entire Tuple object as a hash key:
Object payload = template.opsForHash().get(payLoadKey, suggestion); // suggestion here is a Tuple, but opsForHash().get() expects a String keyThe equivalent code path without scores (line 154) works because suggestion is already a String in that case.
Proposed Solution
The fix appears straightforward - extract the element from the Tuple before using it as a hash key:
Object payload = template.opsForHash().get(payLoadKey, suggestion.getElement());