Closed
Description
In the current implementation, there is an issue with returning the same data twice when querying with Query Methods.
Problem
For example, here's the test code I created.
The expected result seems to be that eddard
and jon
should be returned.
@Test
void shouldReturnEntitiesWithoutDuplicates() {
Person eddard = new Person("eddard", "stark");
eddard.setAlive(true);
Person robb = new Person("robb", "stark");
robb.setAlive(false);
Person jon = new Person("jon", "snow");
jon.setAlive(true);
repo.saveAll(Arrays.asList(eddard, robb, jon));
List<Person> result = repo.findByFirstnameAndLastnameOrAliveIsTrue("eddard", "stark");
assertThat(result).hasSize(2);
assertThat(result).contains(eddard, jon);
}
However, the actual result is that two identical eddards and one jon are returned.
Cause of the problem
The fix is simple. Just make sure to remove duplicate values before running the query.
private <T> List<T> doFind(RedisOperationChain criteria, long offset, int rows, String keyspace, Class<T> type) {
// ...
RedisCallback<Map<byte[], Map<byte[], byte[]>>> callback = connection -> {
List<byte[]> allKeys = new ArrayList<>();
if (!criteria.getSismember().isEmpty()) {
allKeys.addAll(connection.sInter(keys(keyspace + ":", criteria.getSismember())));
}
if (!criteria.getOrSismember().isEmpty()) {
allKeys.addAll(connection.sUnion(keys(keyspace + ":", criteria.getOrSismember())));
}
Looking at the code in RedisQueryEngine
, there is no logic to remove duplicate data that exists in sismember
and orSismember
. so if the same entity fits multiple conditions, it may be returned as a duplicate.
Additional Context
Note that if we modify the logic, we'll need to do the same for RedisQueryEngine#count
.