Pass-thru byte arrays in entities into Bucket.
MappingRedisConverter now accepts data for byte arrays as single property to avoid flattening out binary data into a collection form. We still accept data in a collection form to retain compatibility. Closes: #1981 Original Pull Request: #2015
This commit is contained in:
committed by
Christoph Strobl
parent
b2349fd1ea
commit
d5ba93cc25
@@ -97,7 +97,7 @@ public class Bucket {
|
||||
/**
|
||||
* Get value assigned with path.
|
||||
*
|
||||
* @param path path must not be {@literal null} or {@link String#isEmpty()}.
|
||||
* @param path must not be {@literal null} or {@link String#isEmpty()}.
|
||||
* @return {@literal null} if not set.
|
||||
*/
|
||||
@Nullable
|
||||
@@ -107,6 +107,17 @@ public class Bucket {
|
||||
return data.get(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether {@code path} is associated with a non-{@code null} value.
|
||||
*
|
||||
* @param path must not be {@literal null} or {@link String#isEmpty()}.
|
||||
* @return {@literal true} if the {@code path} is associated with a non-{@code null} value.
|
||||
* @since 2.5
|
||||
*/
|
||||
public boolean hasValue(String path) {
|
||||
return get(path) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* A set view of the mappings contained in this bucket.
|
||||
*
|
||||
|
||||
@@ -283,8 +283,18 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
|
||||
if (typeInformation.isCollectionLike()) {
|
||||
|
||||
return readCollectionOrArray(currentPath, typeInformation.getType(),
|
||||
typeInformation.getRequiredComponentType().getActualType().getType(), source.getBucket());
|
||||
if (isByteArray(typeInformation)) {
|
||||
|
||||
// accept collection form for byte[] if there's no dedicated key
|
||||
if (!source.getBucket().hasValue(currentPath) && isByteArray(typeInformation)) {
|
||||
|
||||
return readCollectionOrArray(currentPath, typeInformation.getType(),
|
||||
typeInformation.getRequiredComponentType().getActualType().getType(), source.getBucket());
|
||||
}
|
||||
} else {
|
||||
return readCollectionOrArray(currentPath, typeInformation.getType(),
|
||||
typeInformation.getRequiredComponentType().getActualType().getType(), source.getBucket());
|
||||
}
|
||||
}
|
||||
|
||||
if (persistentProperty.isEntity()
|
||||
@@ -309,7 +319,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
return sourceBytes == null ? fromBytes(sourceBytes, typeInformation.getActualType().getType()) : source.getId();
|
||||
}
|
||||
|
||||
Class<?> typeToUse = getTypeHint(currentPath, source.getBucket(), persistentProperty.getActualType());
|
||||
Class<?> typeToUse = getTypeHint(currentPath, source.getBucket(), persistentProperty.getType());
|
||||
return fromBytes(sourceBytes, typeToUse);
|
||||
}
|
||||
|
||||
@@ -508,7 +518,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
sink.getBucket().put(pUpdate.getPropertyPath(), toBytes(ref.getKeySpace() + ":" + refId));
|
||||
}
|
||||
}
|
||||
} else if (targetProperty.isCollectionLike()) {
|
||||
} else if (targetProperty.isCollectionLike() && !isByteArray(targetProperty)) {
|
||||
|
||||
Collection<?> collection = pUpdate.getValue() instanceof Collection ? (Collection<?>) pUpdate.getValue()
|
||||
: Collections.singleton(pUpdate.getValue());
|
||||
@@ -595,6 +605,11 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
return;
|
||||
}
|
||||
|
||||
if (value instanceof byte[]) {
|
||||
sink.getBucket().put(StringUtils.hasText(path) ? path : "_raw", (byte[]) value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.getClass() != typeHint.getType()) {
|
||||
typeMapper.writeType(value.getClass(), sink.getBucket().getPropertyPath(path));
|
||||
}
|
||||
@@ -620,7 +635,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
if (propertyValue != null) {
|
||||
writeMap(keyspace, propertyStringPath, persistentProperty.getMapValueType(), (Map<?, ?>) propertyValue, sink);
|
||||
}
|
||||
} else if (persistentProperty.isCollectionLike()) {
|
||||
} else if (persistentProperty.isCollectionLike() && !isByteArray(persistentProperty)) {
|
||||
|
||||
if (propertyValue == null) {
|
||||
writeCollection(keyspace, propertyStringPath, null,
|
||||
@@ -753,6 +768,11 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
return;
|
||||
}
|
||||
|
||||
if (value instanceof byte[]) {
|
||||
sink.getBucket().put(path, toBytes(value));
|
||||
return;
|
||||
}
|
||||
|
||||
if (customConversions.hasCustomWriteTarget(value.getClass())) {
|
||||
|
||||
Optional<Class<?>> targetType = customConversions.getCustomWriteTarget(value.getClass());
|
||||
@@ -969,6 +989,11 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
* @throws ConverterNotFoundException
|
||||
*/
|
||||
public <T> T fromBytes(byte[] source, Class<T> type) {
|
||||
|
||||
if (type.isInstance(source)) {
|
||||
return type.cast(source);
|
||||
}
|
||||
|
||||
return conversionService.convert(source, type);
|
||||
}
|
||||
|
||||
@@ -1055,6 +1080,14 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
customConversions.registerConvertersIn(conversionService);
|
||||
}
|
||||
|
||||
private static boolean isByteArray(RedisPersistentProperty property) {
|
||||
return property.getType().equals(byte[].class);
|
||||
}
|
||||
|
||||
private static boolean isByteArray(TypeInformation<?> type) {
|
||||
return type.getType().equals(byte[].class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
|
||||
Reference in New Issue
Block a user