Skip to content

Gson.fromJson fails due to malformed JSON created by StringBuilder for projected string fields with spaces. #676

@alpha0301

Description

@alpha0301

(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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions