-
Notifications
You must be signed in to change notification settings - Fork 102
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
@AutoComplete
and@AutoCompletePayload
annotations:
@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 key
The 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());