-
Notifications
You must be signed in to change notification settings - Fork 102
Description
(Hello, I am a Korean user and this bug report was written with the assistance of an AI. Please excuse any awkward phrasing or grammatical errors.)
Describe the bug
When using FT.SEARCH with projections (RETURN clause) in redis-om-spring v1.0.4, a JsonSyntaxException occurs if a projected TEXT field contains a value with spaces (e.g., "메이크업 스파츌라 프리미엄").
The root cause is within the RediSearchQuery.java class, specifically in the parseDocumentResult method. The logic manually builds a JSON string using StringBuilder but fails to enclose string values in double quotes if they contain spaces and the field name is not explicitly handled (like "name"). This results in a malformed JSON string (e.g., {"keyword": a b c} instead of {"keyword": "a b c"}), which Gson.fromJson cannot parse.
Steps to Reproduce
Create a Document with a @searchable text field (e.g., keyword).
Save an entity where the keyword value contains spaces (e.g., "makeup spatula premium").
Create a repository method using @query that returns a projection of this field.
Execute the query.
A com.google.gson.JsonSyntaxException is thrown.
Expected behavior
The parseDocumentResult method should correctly serialize projected fields into a valid JSON string, properly quoting all string values, so that Gson.fromJson can successfully deserialize it into the domain object.
Code snippet with the issue
The issue is in the final else block of the JSON building logic within RediSearchQuery.java -> parseDocumentResult:
// ...
} else {
// This part incorrectly appends string values without quotes
jsonBuilder.append(valueStr);
}
// ...
String jsonFromFields = jsonBuilder.toString(); // This string is malformed
entity = gsonInstance.fromJson(jsonFromFields, domainType); // Exception thrown here
Proposed Solutions
I would like to suggest two potential solutions:
Minimal Fix (Use Gson's Tree Model): Instead of manually building the JSON string with StringBuilder, use Gson's own JsonObject builder. This is a safer approach as it handles quoting and escaping automatically.
JsonObject jsonObject = new JsonObject();
for (Entry<String, Object> entry : fieldMap.entrySet()) {
jsonObject.addProperty(entry.getKey(), entry.getValue().toString());
}
String jsonFromFields = jsonObject.toString();
entity = gsonInstance.fromJson(jsonFromFields, domainType);
Recommended Fix (Align with Spring Ecosystem - Use Jackson): The Spring ecosystem's standard for JSON processing is Jackson (ObjectMapper). Replacing Gson with Jackson would offer more robust and flexible object mapping. The entire faulty StringBuilder logic could be replaced with a single, safe call:
// Assuming an ObjectMapper instance is available
entity = objectMapper.convertValue(fieldMap, domainType);
This approach is more idiomatic for a Spring library and eliminates the need for intermediate JSON string creation altogether, preventing this class of bug entirely.