Consider target type when calling getAllOf(…).
We now accept a type hint when calling getAllOf(…) to avoid materializing null instances when the actual type hint cannot resolve to an entity. Closes #1995 Original Pull Request: #1996
This commit is contained in:
committed by
Christoph Strobl
parent
754fac92be
commit
e496c19021
@@ -373,16 +373,21 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
|
||||
*/
|
||||
@Override
|
||||
public List<?> getAllOf(String keyspace) {
|
||||
return getAllOf(keyspace, -1, -1);
|
||||
return getAllOf(keyspace, Object.class, -1, -1);
|
||||
}
|
||||
|
||||
public List<?> getAllOf(String keyspace, long offset, int rows) {
|
||||
@Override
|
||||
public <T> Iterable<T> getAllOf(String keyspace, Class<T> type) {
|
||||
return getAllOf(keyspace, type, -1, -1);
|
||||
}
|
||||
|
||||
public <T> List<T> getAllOf(String keyspace, Class<T> type, long offset, int rows) {
|
||||
|
||||
byte[] binKeyspace = toBytes(keyspace);
|
||||
|
||||
Set<byte[]> ids = redisOps.execute((RedisCallback<Set<byte[]>>) connection -> connection.sMembers(binKeyspace));
|
||||
|
||||
List<Object> result = new ArrayList<>();
|
||||
List<T> result = new ArrayList<>();
|
||||
List<byte[]> keys = new ArrayList<>(ids);
|
||||
|
||||
if (keys.isEmpty() || keys.size() < offset) {
|
||||
@@ -395,7 +400,7 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
|
||||
}
|
||||
|
||||
for (byte[] key : keys) {
|
||||
result.add(get(key, keyspace));
|
||||
result.add(get(key, keyspace, type));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ class RedisQueryEngine extends QueryEngine<RedisKeyValueAdapter, RedisOperationC
|
||||
if (criteria == null
|
||||
|| (CollectionUtils.isEmpty(criteria.getOrSismember()) && CollectionUtils.isEmpty(criteria.getSismember()))
|
||||
&& criteria.getNear() == null) {
|
||||
return (Collection<T>) getAdapter().getAllOf(keyspace, offset, rows);
|
||||
return getAdapter().getAllOf(keyspace, type, offset, rows);
|
||||
}
|
||||
|
||||
RedisCallback<Map<byte[], Map<byte[], byte[]>>> callback = connection -> {
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.Reference;
|
||||
import org.springframework.data.annotation.TypeAlias;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.keyvalue.annotation.KeySpace;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
@@ -62,6 +63,7 @@ public class RedisKeyValueAdapterTests {
|
||||
private RedisKeyValueAdapter adapter;
|
||||
private StringRedisTemplate template;
|
||||
private RedisConnectionFactory connectionFactory;
|
||||
private RedisMappingContext mappingContext;
|
||||
|
||||
public RedisKeyValueAdapterTests(RedisConnectionFactory connectionFactory) throws Exception {
|
||||
this.connectionFactory = connectionFactory;
|
||||
@@ -73,7 +75,7 @@ public class RedisKeyValueAdapterTests {
|
||||
template = new StringRedisTemplate(connectionFactory);
|
||||
template.afterPropertiesSet();
|
||||
|
||||
RedisMappingContext mappingContext = new RedisMappingContext(
|
||||
mappingContext = new RedisMappingContext(
|
||||
new MappingConfiguration(new IndexConfiguration(), new KeyspaceConfiguration()));
|
||||
mappingContext.afterPropertiesSet();
|
||||
|
||||
@@ -225,6 +227,34 @@ public class RedisKeyValueAdapterTests {
|
||||
assertThat(((Person) loaded).address.country).isEqualTo("Andor");
|
||||
}
|
||||
|
||||
@Test // #1995
|
||||
void getAllOfShouldReturnSuperTypeIfForUnregisteredTypeAlias() {
|
||||
|
||||
Map<String, String> map = new LinkedHashMap<>();
|
||||
map.put("_class", "taveren");
|
||||
map.put("address.country", "Andor");
|
||||
template.opsForHash().putAll("persons:load-1", map);
|
||||
|
||||
Object loaded = adapter.get("load-1", "persons", Person.class);
|
||||
|
||||
assertThat(loaded).isExactlyInstanceOf(Person.class);
|
||||
}
|
||||
|
||||
@Test // #1995
|
||||
void getAllOfShouldReturnCorrectTypeIfForRegisteredTypeAlias() {
|
||||
|
||||
mappingContext.getPersistentEntity(TaVeren.class);
|
||||
|
||||
Map<String, String> map = new LinkedHashMap<>();
|
||||
map.put("_class", "taveren");
|
||||
map.put("address.country", "Andor");
|
||||
template.opsForHash().putAll("persons:load-1", map);
|
||||
|
||||
Object loaded = adapter.get("load-1", "persons", Person.class);
|
||||
|
||||
assertThat(loaded).isExactlyInstanceOf(TaVeren.class);
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-425
|
||||
void couldReadsKeyspaceSizeCorrectly() {
|
||||
|
||||
@@ -826,6 +856,7 @@ public class RedisKeyValueAdapterTests {
|
||||
String postcode;
|
||||
}
|
||||
|
||||
@TypeAlias("taveren")
|
||||
static class TaVeren extends Person {
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user