DATAREDIS-849 - Add support for immutable objects.
We now support immutable objects for saving (e.g. object without a provided Id) and loading (i.e. persistence constructor declares a subset of properties). New instances are created using wither methods/Kotlin copy(…) methods if an immutable object requires association with an Id. Association of the Id to its object moved from RedisKeyValueAdapter to RedisKeyValueTemplate.
This commit is contained in:
committed by
Oliver Gierke
parent
3defab118e
commit
322cfabb17
@@ -36,7 +36,7 @@ import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.ConverterNotFoundException;
|
||||
import org.springframework.data.keyvalue.core.AbstractKeyValueAdapter;
|
||||
import org.springframework.data.keyvalue.core.KeyValueAdapter;
|
||||
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty;
|
||||
import org.springframework.data.mapping.PersistentPropertyAccessor;
|
||||
import org.springframework.data.redis.connection.DataType;
|
||||
import org.springframework.data.redis.connection.Message;
|
||||
import org.springframework.data.redis.connection.MessageListener;
|
||||
@@ -217,15 +217,7 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
|
||||
}
|
||||
|
||||
if (rdo.getId() == null) {
|
||||
|
||||
rdo.setId(converter.getConversionService().convert(id, String.class));
|
||||
|
||||
if (!(item instanceof RedisData)) {
|
||||
KeyValuePersistentProperty idProperty = converter.getMappingContext()
|
||||
.getRequiredPersistentEntity(item.getClass()).getRequiredIdProperty();
|
||||
converter.getMappingContext().getRequiredPersistentEntity(item.getClass()).getPropertyAccessor(item)
|
||||
.setProperty(idProperty, id);
|
||||
}
|
||||
}
|
||||
|
||||
redisOps.execute((RedisCallback<Object>) connection -> {
|
||||
@@ -624,8 +616,13 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
|
||||
});
|
||||
|
||||
if (timeout != null || !ttlProperty.getType().isPrimitive()) {
|
||||
entity.getPropertyAccessor(target).setProperty(ttlProperty,
|
||||
|
||||
PersistentPropertyAccessor<T> propertyAccessor = entity.getPropertyAccessor(target);
|
||||
|
||||
propertyAccessor.setProperty(ttlProperty,
|
||||
converter.getConversionService().convert(timeout, ttlProperty.getType()));
|
||||
|
||||
target = propertyAccessor.getBean();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,12 @@ import java.util.List;
|
||||
import org.springframework.data.keyvalue.core.KeyValueAdapter;
|
||||
import org.springframework.data.keyvalue.core.KeyValueCallback;
|
||||
import org.springframework.data.keyvalue.core.KeyValueTemplate;
|
||||
import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty;
|
||||
import org.springframework.data.mapping.PersistentPropertyAccessor;
|
||||
import org.springframework.data.redis.core.convert.RedisConverter;
|
||||
import org.springframework.data.redis.core.convert.RedisData;
|
||||
import org.springframework.data.redis.core.mapping.RedisMappingContext;
|
||||
import org.springframework.data.redis.core.mapping.RedisPersistentEntity;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
@@ -127,14 +131,31 @@ public class RedisKeyValueTemplate extends KeyValueTemplate {
|
||||
* @see org.springframework.data.keyvalue.core.KeyValueTemplate#insert(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void insert(Object id, Object objectToInsert) {
|
||||
public <T> T insert(Object id, T objectToInsert) {
|
||||
|
||||
if (objectToInsert instanceof PartialUpdate) {
|
||||
doPartialUpdate((PartialUpdate<?>) objectToInsert);
|
||||
return;
|
||||
return objectToInsert;
|
||||
}
|
||||
|
||||
super.insert(id, objectToInsert);
|
||||
if (!(objectToInsert instanceof RedisData)) {
|
||||
|
||||
RedisConverter converter = adapter.getConverter();
|
||||
|
||||
RedisPersistentEntity<?> entity = converter.getMappingContext()
|
||||
.getRequiredPersistentEntity(objectToInsert.getClass());
|
||||
|
||||
KeyValuePersistentProperty idProperty = entity.getRequiredIdProperty();
|
||||
PersistentPropertyAccessor<T> propertyAccessor = entity.getPropertyAccessor(objectToInsert);
|
||||
|
||||
if (propertyAccessor.getProperty(idProperty) == null) {
|
||||
|
||||
propertyAccessor.setProperty(idProperty, id);
|
||||
return super.insert(id, propertyAccessor.getBean());
|
||||
}
|
||||
}
|
||||
|
||||
return super.insert(id, objectToInsert);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -142,14 +163,20 @@ public class RedisKeyValueTemplate extends KeyValueTemplate {
|
||||
* @see org.springframework.data.keyvalue.core.KeyValueTemplate#update(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void update(Object objectToUpdate) {
|
||||
public <T> T update(T objectToUpdate) {
|
||||
|
||||
if (objectToUpdate instanceof PartialUpdate) {
|
||||
doPartialUpdate((PartialUpdate<?>) objectToUpdate);
|
||||
return;
|
||||
|
||||
return objectToUpdate;
|
||||
}
|
||||
|
||||
super.update(objectToUpdate);
|
||||
return super.update(objectToUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T update(Object id, T objectToUpdate) {
|
||||
return super.update(id, objectToUpdate);
|
||||
}
|
||||
|
||||
protected void doPartialUpdate(final PartialUpdate<?> update) {
|
||||
|
||||
@@ -211,7 +211,11 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
R instance = (R) conversionService.convert(partial, readType.getType());
|
||||
|
||||
if (entity != null && entity.hasIdProperty()) {
|
||||
entity.getPropertyAccessor(instance).setProperty(entity.getRequiredIdProperty(), source.getId());
|
||||
|
||||
PersistentPropertyAccessor<R> propertyAccessor = entity.getPropertyAccessor(instance);
|
||||
|
||||
propertyAccessor.setProperty(entity.getRequiredIdProperty(), source.getId());
|
||||
instance = propertyAccessor.getBean();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
@@ -246,7 +250,7 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean {
|
||||
|
||||
readAssociation(path, source, entity, accessor);
|
||||
|
||||
return (R) instance;
|
||||
return (R) accessor.getBean();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
Reference in New Issue
Block a user