DATAREDIS-547 - Fix query execution when derived criteria is empty.

We now make sure to pipe finder queries without any criteria to the according find all method. This allows usage of `PagingAndSortingRepository.findAllBy(Pageable page)` as well as finders without any criteria like `findTop3By()`.

Original pull request: #216.
This commit is contained in:
Christoph Strobl
2016-08-24 10:08:58 +02:00
committed by Mark Paluch
parent d4af51e77d
commit 83ff5ec85b
4 changed files with 111 additions and 15 deletions

View File

@@ -60,7 +60,6 @@ import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.util.ByteUtils;
import org.springframework.data.util.CloseableIterator;
import org.springframework.util.Assert;
import org.springframework.util.NumberUtils;
import org.springframework.util.ObjectUtils;
/**
@@ -346,6 +345,10 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
* @see org.springframework.data.keyvalue.core.KeyValueAdapter#getAllOf(java.io.Serializable)
*/
public List<?> getAllOf(final Serializable keyspace) {
return getAllOf(keyspace, -1, -1);
}
public List<?> getAllOf(final Serializable keyspace, int offset, int rows) {
final byte[] binKeyspace = toBytes(keyspace);
@@ -358,7 +361,15 @@ public class RedisKeyValueAdapter extends AbstractKeyValueAdapter
});
List<Object> result = new ArrayList<Object>();
for (byte[] key : ids) {
List<byte[]> keys = new ArrayList<byte[]>(ids);
offset = Math.max(0, offset);
if (offset >= 0 && rows > 0) {
keys = keys.subList(offset, Math.min(offset + rows, keys.size()));
}
for (byte[] key : keys) {
result.add(get(key, keyspace));
}
return result;

View File

@@ -34,6 +34,7 @@ import org.springframework.data.redis.core.convert.RedisData;
import org.springframework.data.redis.repository.query.RedisOperationChain;
import org.springframework.data.redis.repository.query.RedisOperationChain.PathAndValue;
import org.springframework.data.redis.util.ByteUtils;
import org.springframework.util.CollectionUtils;
/**
* Redis specific {@link QueryEngine} implementation.
@@ -67,9 +68,15 @@ class RedisQueryEngine extends QueryEngine<RedisKeyValueAdapter, RedisOperationC
* @see org.springframework.data.keyvalue.core.QueryEngine#execute(java.lang.Object, java.lang.Object, int, int, java.io.Serializable, java.lang.Class)
*/
@Override
@SuppressWarnings("unchecked")
public <T> Collection<T> execute(final RedisOperationChain criteria, final Comparator<?> sort, final int offset,
final int rows, final Serializable keyspace, Class<T> type) {
if (criteria == null
|| (CollectionUtils.isEmpty(criteria.getOrSismember()) && CollectionUtils.isEmpty(criteria.getSismember()))) {
return (Collection<T>) getAdapter().getAllOf(keyspace, offset, rows);
}
RedisCallback<Map<byte[], Map<byte[], byte[]>>> callback = new RedisCallback<Map<byte[], Map<byte[], byte[]>>>() {
@Override
@@ -99,8 +106,9 @@ class RedisQueryEngine extends QueryEngine<RedisKeyValueAdapter, RedisOperationC
return Collections.emptyMap();
}
if (offset >= 0 && rows > 0) {
allKeys = allKeys.subList(Math.max(0, offset), Math.min(offset + rows, allKeys.size()));
int offsetToUse = Math.max(0, offset);
if (rows > 0) {
allKeys = allKeys.subList(Math.max(0, offsetToUse), Math.min(offsetToUse + rows, allKeys.size()));
}
for (byte[] id : allKeys) {
@@ -171,8 +179,8 @@ class RedisQueryEngine extends QueryEngine<RedisKeyValueAdapter, RedisOperationC
int i = 0;
for (PathAndValue pathAndValue : source) {
byte[] convertedValue = getAdapter().getConverter().getConversionService()
.convert(pathAndValue.getFirstValue(), byte[].class);
byte[] convertedValue = getAdapter().getConverter().getConversionService().convert(pathAndValue.getFirstValue(),
byte[].class);
byte[] fullPath = getAdapter().getConverter().getConversionService()
.convert(prefix + pathAndValue.getPath() + ":", byte[].class);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015 the original author or authors.
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@ import org.springframework.data.repository.query.ParameterAccessor;
import org.springframework.data.repository.query.parser.AbstractQueryCreator;
import org.springframework.data.repository.query.parser.Part;
import org.springframework.data.repository.query.parser.PartTree;
import org.springframework.util.CollectionUtils;
/**
* Redis specific query creator.
@@ -87,11 +88,13 @@ public class RedisQueryCreator extends AbstractQueryCreator<KeyValueQuery<RedisO
KeyValueQuery<RedisOperationChain> query = new KeyValueQuery<RedisOperationChain>(criteria);
if (query.getCritieria().getSismember().size() == 1 && query.getCritieria().getOrSismember().size() == 1) {
if (query.getCritieria() != null && !CollectionUtils.isEmpty(query.getCritieria().getSismember())
&& !CollectionUtils.isEmpty(query.getCritieria().getOrSismember()))
if (query.getCritieria().getSismember().size() == 1 && query.getCritieria().getOrSismember().size() == 1) {
query.getCritieria().getOrSismember().add(query.getCritieria().getSismember().iterator().next());
query.getCritieria().getSismember().clear();
}
query.getCritieria().getOrSismember().add(query.getCritieria().getSismember().iterator().next());
query.getCritieria().getSismember().clear();
}
if (sort != null) {
query.setSort(sort);