Description
redis-om-spring.version: 0.8.3
The same NullPointer happens in 2 scenario's:
- One of the requested Return fields (either nested or on root level) is null
- The search stream does not compose the right query when using nested fields as mapped return values.
Having a nested object:
public class NestedObject {
@Indexed
private String nestedProperty;
}
Having a product with property on root and a nested property:
@Document
public class Product {
...
@Indexed
private String colorCode;
@Indexed
private NestedObject nestedObject;
...
}
When building a searchstream and mapping only 2 fields:
entityStream.of(Product.class)
.map(Fields.of(Product$.NESTED_OBJECT_NESTED_PROPERTY, Product$.COLOR_CODE))
.collect(Collectors.toList());
This results in a NullPointer exception while parsing the result:
java.lang.NullPointerException: Cannot read the array length because "bytes" is null
at java.base/java.lang.String.<init>(String.java:1382)
at redis.clients.jedis.util.SafeEncoder.encode(SafeEncoder.java:35)
at com.redis.om.spring.search.stream.ReturnFieldsSearchStreamImpl.lambda$toResultTuple$5(ReturnFieldsSearchStreamImpl.java:308)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at com.redis.om.spring.search.stream.ReturnFieldsSearchStreamImpl.lambda$toResultTuple$6(ReturnFieldsSearchStreamImpl.java:306)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at com.redis.om.spring.search.stream.ReturnFieldsSearchStreamImpl.toResultTuple(ReturnFieldsSearchStreamImpl.java:301)
at com.redis.om.spring.search.stream.ReturnFieldsSearchStreamImpl.resolveStream(ReturnFieldsSearchStreamImpl.java:290)
at com.redis.om.spring.search.stream.ReturnFieldsSearchStreamImpl.collect(ReturnFieldsSearchStreamImpl.java:220)
SCENARIO 1:
This happens in scenario 1, when one of the products has a null value in Redis for one of the requested properties. In this case when one of the product.colorCode is NULL, the Nullpointer is is thrown while parsing to result tuples.
SCENARIO 2:
This happens in scenario 2 when the result from Redis does not contain the expected Product$.NESTED_OBJECT_NESTED_PROPERTY, field, instead only the root property is returned.
Outgoing query:
"FT.SEARCH" "nl.domain.products.ProductIdx" "LIMIT" "0" "10000" "RETURN" "2" "$.nestedObject_nestedProperty" "$.colorCode" "DIALECT" "1"
Partial Response:
4744) "nl.domain.products.Product:2372"
4745) 1) "$.colorCode"
2) "90"
When I manualy fire a query but change the underscore '$.nestedObject_nestedProperty' to a dot '$.nestedObject.nestedProperty', the query does have expected result and null pointer disappears:
"FT.SEARCH" "nl.domain.products.ProductIdx" "LIMIT" "0" "10000" "RETURN" "2" "$.nestedObject.nestedProperty" "$.colorCode" "DIALECT" "1"
Partial Response:
4744) "nl.domain.products.Product:2372"
4745) 1) "$.nestedObject.nestedProperty"
2) "Men"
3) "$.colorCode"
4) "90"
Additional note: when using the nested field within a search query, the field DOES work with an underscore in the query:
"FT.SEARCH" "nl.domain.products.ProductIdx" "(@nestedObject_nestedProperty:{MEN})"
So it seems the query should have underscore for the nested field when used as query param, but should not have the underscore when used as return value (which seems inconsistent from Redis). Scanning the code, in both cases the searchAlias of the searchField is used (containing underscore)