diff --git a/src/main/java/org/springframework/data/redis/core/convert/PathIndexResolver.java b/src/main/java/org/springframework/data/redis/core/convert/PathIndexResolver.java index bcfacf2c88..fe18e8576e 100644 --- a/src/main/java/org/springframework/data/redis/core/convert/PathIndexResolver.java +++ b/src/main/java/org/springframework/data/redis/core/convert/PathIndexResolver.java @@ -55,7 +55,7 @@ */ public class PathIndexResolver implements IndexResolver { - private final Set> VALUE_TYPES = new HashSet<>(Arrays.> asList(Point.class, GeoLocation.class)); + private static final Set> VALUE_TYPES = new HashSet<>(Arrays.asList(Point.class, GeoLocation.class)); private final ConfigurableIndexDefinitionProvider indexConfiguration; private final RedisMappingContext mappingContext; @@ -83,13 +83,14 @@ public PathIndexResolver(RedisMappingContext mappingContext) { } public Set resolveIndexesFor(TypeInformation typeInformation, @Nullable Object value) { - return doResolveIndexesFor(mappingContext.getRequiredPersistentEntity(typeInformation).getKeySpace(), "", - typeInformation, null, value); + String keyspace = mappingContext.getRequiredPersistentEntity(typeInformation).getKeySpace(); + Assert.notNull(keyspace, "Keyspace for type " + typeInformation + " must not be null!"); + return doResolveIndexesFor(keyspace, "", typeInformation, null, value); } @Override public Set resolveIndexesFor(String keyspace, String path, TypeInformation typeInformation, - Object value) { + @Nullable Object value) { return doResolveIndexesFor(keyspace, path, typeInformation, null, value); } @@ -109,80 +110,60 @@ private Set doResolveIndexesFor(final String keyspace, final String return resolveIndex(keyspace, path, entity.getPersistentProperty(propertyName), value); } - final PersistentPropertyAccessor accessor = entity.getPropertyAccessor(value); + final PersistentPropertyAccessor accessor = entity.getPropertyAccessor(value); final Set indexes = new LinkedHashSet<>(); - entity.doWithProperties(new PropertyHandler() { + entity.doWithProperties((PropertyHandler) persistentProperty -> { - @Override - public void doWithPersistentProperty(RedisPersistentProperty persistentProperty) { + String currentPath = !path.isEmpty() ? path + "." + persistentProperty.getName() : persistentProperty.getName(); - String currentPath = !path.isEmpty() ? path + "." + persistentProperty.getName() : persistentProperty.getName(); + Object propertyValue = accessor.getProperty(persistentProperty); - Object propertyValue = accessor.getProperty(persistentProperty); - - if (propertyValue == null) { - return; - } - - TypeInformation typeHint = persistentProperty.isMap() - ? persistentProperty.getTypeInformation().getRequiredMapValueType() - : persistentProperty.getTypeInformation().getActualType(); - - if (persistentProperty.isMap()) { - - for (Entry entry : ((Map) propertyValue).entrySet()) { - - TypeInformation typeToUse = updateTypeHintForActualValue(typeHint, entry.getValue()); - indexes.addAll(doResolveIndexesFor(keyspace, currentPath + "." + entry.getKey(), typeToUse.getActualType(), - persistentProperty, entry.getValue())); - } - - } else if (persistentProperty.isCollectionLike()) { + if (propertyValue == null) { + return; + } - final Iterable iterable; + TypeInformation typeHint = persistentProperty.isMap() + ? persistentProperty.getTypeInformation().getRequiredMapValueType() + : persistentProperty.getTypeInformation().getActualType(); - if (Iterable.class.isAssignableFrom(propertyValue.getClass())) { - iterable = (Iterable) propertyValue; - } else if (propertyValue.getClass().isArray()) { - iterable = CollectionUtils.arrayToList(propertyValue); - } else { - throw new RuntimeException("Don't know how to handle " + propertyValue.getClass() + " type of collection"); - } + if (persistentProperty.isMap()) { - for (Object listValue : iterable) { + for (Entry entry : ((Map) propertyValue).entrySet()) { - if (listValue != null) { - TypeInformation typeToUse = updateTypeHintForActualValue(typeHint, listValue); - indexes.addAll( - doResolveIndexesFor(keyspace, currentPath, typeToUse.getActualType(), persistentProperty, listValue)); - } - } + TypeInformation typeToUse = updateTypeHintForActualValue(typeHint, entry.getValue()); + indexes.addAll(doResolveIndexesFor(keyspace, currentPath + "." + entry.getKey(), typeToUse.getActualType(), + persistentProperty, entry.getValue())); } - else if (persistentProperty.isEntity() - || persistentProperty.getTypeInformation().getActualType().equals(TypeInformation.OBJECT)) { + } else if (persistentProperty.isCollectionLike()) { + + final Iterable iterable; - typeHint = updateTypeHintForActualValue(typeHint, propertyValue); - indexes.addAll( - doResolveIndexesFor(keyspace, currentPath, typeHint.getActualType(), persistentProperty, propertyValue)); + if (Iterable.class.isAssignableFrom(propertyValue.getClass())) { + iterable = (Iterable) propertyValue; + } else if (propertyValue.getClass().isArray()) { + iterable = CollectionUtils.arrayToList(propertyValue); } else { - indexes.addAll(resolveIndex(keyspace, currentPath, persistentProperty, propertyValue)); + throw new RuntimeException("Don't know how to handle " + propertyValue.getClass() + " type of collection"); } - } + for (Object listValue : iterable) { - private TypeInformation updateTypeHintForActualValue(TypeInformation typeHint, Object propertyValue) { - - if (typeHint.equals(TypeInformation.OBJECT) || typeHint.getClass().isInterface()) { - try { - typeHint = mappingContext.getRequiredPersistentEntity(propertyValue.getClass()).getTypeInformation(); - } catch (Exception ignore) { - // ignore for cases where property value cannot be resolved as an entity, in that case - // the provided type hint has to be sufficient + if (listValue != null) { + TypeInformation typeToUse = updateTypeHintForActualValue(typeHint, listValue); + indexes.addAll( + doResolveIndexesFor(keyspace, currentPath, typeToUse.getActualType(), persistentProperty, listValue)); } } - return typeHint; + } else if (persistentProperty.isEntity() + || persistentProperty.getTypeInformation().getActualType().equals(TypeInformation.OBJECT)) { + + typeHint = updateTypeHintForActualValue(typeHint, propertyValue); + indexes.addAll( + doResolveIndexesFor(keyspace, currentPath, typeHint.getActualType(), persistentProperty, propertyValue)); + } else { + indexes.addAll(resolveIndex(keyspace, currentPath, persistentProperty, propertyValue)); } }); @@ -190,6 +171,19 @@ private TypeInformation updateTypeHintForActualValue(TypeInformation typeH return indexes; } + private TypeInformation updateTypeHintForActualValue(TypeInformation typeHint, Object propertyValue) { + + if (typeHint.equals(TypeInformation.OBJECT) || typeHint.getClass().isInterface()) { + try { + typeHint = mappingContext.getRequiredPersistentEntity(propertyValue.getClass()).getTypeInformation(); + } catch (Exception ignore) { + // ignore for cases where property value cannot be resolved as an entity, in that case + // the provided type hint has to be sufficient + } + } + return typeHint; + } + protected Set resolveIndex(String keyspace, String propertyPath, @Nullable PersistentProperty property, @Nullable Object value) {