Add fluent API support for QuerydslKeyValueRepository.
Also reuse ProjectionFactory from repository factory. Closes #397.
This commit is contained in:
@@ -17,9 +17,14 @@ package org.springframework.data.map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.dao.IncorrectResultSizeDataAccessException;
|
||||
@@ -30,27 +35,30 @@ import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.keyvalue.Person;
|
||||
import org.springframework.data.keyvalue.QPerson;
|
||||
import org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactory;
|
||||
import org.springframework.data.keyvalue.repository.support.QuerydslKeyValueRepository;
|
||||
import org.springframework.data.map.QuerydslKeyValueRepositoryUnitTests.QPersonRepository;
|
||||
import org.springframework.data.map.QuerydslKeyValuePredicateExecutorUnitTests.QPersonRepository;
|
||||
import org.springframework.data.querydsl.QSort;
|
||||
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
|
||||
import org.springframework.data.repository.query.FluentQuery;
|
||||
import org.springframework.data.util.Streamable;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link QuerydslKeyValueRepository}.
|
||||
* Unit tests for {@link org.springframework.data.keyvalue.repository.support.QuerydslKeyValuePredicateExecutor}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class QuerydslKeyValueRepositoryUnitTests extends AbstractRepositoryUnitTests<QPersonRepository> {
|
||||
class QuerydslKeyValuePredicateExecutorUnitTests extends AbstractRepositoryUnitTests<QPersonRepository> {
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
repository.saveAll(LENNISTERS);
|
||||
}
|
||||
|
||||
@Test // DATACMNS-525
|
||||
void findOneIsExecutedCorrectly() {
|
||||
|
||||
repository.saveAll(LENNISTERS);
|
||||
|
||||
Optional<Person> result = repository.findOne(QPerson.person.firstname.eq(CERSEI.getFirstname()));
|
||||
assertThat(result).hasValue(CERSEI);
|
||||
}
|
||||
@@ -58,8 +66,6 @@ public class QuerydslKeyValueRepositoryUnitTests extends AbstractRepositoryUnitT
|
||||
@Test // DATACMNS-525
|
||||
void findAllIsExecutedCorrectly() {
|
||||
|
||||
repository.saveAll(LENNISTERS);
|
||||
|
||||
Iterable<Person> result = repository.findAll(QPerson.person.age.eq(CERSEI.getAge()));
|
||||
assertThat(result).contains(CERSEI, JAIME);
|
||||
}
|
||||
@@ -67,7 +73,6 @@ public class QuerydslKeyValueRepositoryUnitTests extends AbstractRepositoryUnitT
|
||||
@Test // DATACMNS-525
|
||||
void findWithPaginationWorksCorrectly() {
|
||||
|
||||
repository.saveAll(LENNISTERS);
|
||||
Page<Person> page1 = repository.findAll(QPerson.person.age.eq(CERSEI.getAge()), PageRequest.of(0, 1));
|
||||
|
||||
assertThat(page1.getTotalElements()).isEqualTo(2L);
|
||||
@@ -84,8 +89,6 @@ public class QuerydslKeyValueRepositoryUnitTests extends AbstractRepositoryUnitT
|
||||
@Test // DATACMNS-525
|
||||
void findAllUsingOrderSpecifierWorksCorrectly() {
|
||||
|
||||
repository.saveAll(LENNISTERS);
|
||||
|
||||
Iterable<Person> result = repository.findAll(QPerson.person.age.eq(CERSEI.getAge()),
|
||||
QPerson.person.firstname.desc());
|
||||
|
||||
@@ -95,8 +98,6 @@ public class QuerydslKeyValueRepositoryUnitTests extends AbstractRepositoryUnitT
|
||||
@Test // DATACMNS-525
|
||||
void findAllUsingPageableWithSortWorksCorrectly() {
|
||||
|
||||
repository.saveAll(LENNISTERS);
|
||||
|
||||
Iterable<Person> result = repository.findAll(QPerson.person.age.eq(CERSEI.getAge()),
|
||||
PageRequest.of(0, 10, Direction.DESC, "firstname"));
|
||||
|
||||
@@ -106,8 +107,6 @@ public class QuerydslKeyValueRepositoryUnitTests extends AbstractRepositoryUnitT
|
||||
@Test // DATACMNS-525
|
||||
void findAllUsingPagableWithQSortWorksCorrectly() {
|
||||
|
||||
repository.saveAll(LENNISTERS);
|
||||
|
||||
Iterable<Person> result = repository.findAll(QPerson.person.age.eq(CERSEI.getAge()),
|
||||
PageRequest.of(0, 10, new QSort(QPerson.person.firstname.desc())));
|
||||
|
||||
@@ -117,8 +116,6 @@ public class QuerydslKeyValueRepositoryUnitTests extends AbstractRepositoryUnitT
|
||||
@Test // DATAKV-90
|
||||
void findAllWithOrderSpecifierWorksCorrectly() {
|
||||
|
||||
repository.saveAll(LENNISTERS);
|
||||
|
||||
Iterable<Person> result = repository.findAll(new QSort(QPerson.person.firstname.desc()));
|
||||
|
||||
assertThat(result).containsExactly(TYRION, JAIME, CERSEI);
|
||||
@@ -132,8 +129,6 @@ public class QuerydslKeyValueRepositoryUnitTests extends AbstractRepositoryUnitT
|
||||
@Test // DATAKV-90, DATAKV-197
|
||||
void findAllShouldAllowUnsortedFindAll() {
|
||||
|
||||
repository.saveAll(LENNISTERS);
|
||||
|
||||
Iterable<Person> result = repository.findAll(Sort.unsorted());
|
||||
|
||||
assertThat(result).contains(TYRION, JAIME, CERSEI);
|
||||
@@ -141,17 +136,12 @@ public class QuerydslKeyValueRepositoryUnitTests extends AbstractRepositoryUnitT
|
||||
|
||||
@Test // DATAKV-95
|
||||
void executesExistsCorrectly() {
|
||||
|
||||
repository.saveAll(LENNISTERS);
|
||||
|
||||
assertThat(repository.exists(QPerson.person.age.eq(CERSEI.getAge()))).isTrue();
|
||||
}
|
||||
|
||||
@Test // DATAKV-96
|
||||
void shouldSupportFindAllWithPredicateAndSort() {
|
||||
|
||||
repository.saveAll(LENNISTERS);
|
||||
|
||||
List<Person> users = Streamable.of(repository.findAll(person.age.gt(0), Sort.by(Direction.ASC, "firstname")))
|
||||
.toList();
|
||||
|
||||
@@ -164,12 +154,148 @@ public class QuerydslKeyValueRepositoryUnitTests extends AbstractRepositoryUnitT
|
||||
@Test // DATAKV-179
|
||||
void throwsExceptionIfMoreThanOneResultIsFound() {
|
||||
|
||||
repository.saveAll(LENNISTERS);
|
||||
|
||||
assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class) //
|
||||
.isThrownBy(() -> repository.findOne(person.firstname.contains("e")));
|
||||
}
|
||||
|
||||
@Test // GH-397
|
||||
void findByShouldReturnFirst() {
|
||||
|
||||
Person first = repository.findBy(QPerson.person.firstname.eq("tyrion"),
|
||||
FluentQuery.FetchableFluentQuery::firstValue);
|
||||
|
||||
assertThat(first).isEqualTo(TYRION);
|
||||
|
||||
first = repository.findBy(QPerson.person.firstname.eq("foo"), Function.identity()).firstValue();
|
||||
|
||||
assertThat(first).isNull();
|
||||
}
|
||||
|
||||
@Test // GH-397
|
||||
void findByShouldReturnOne() {
|
||||
|
||||
assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class)
|
||||
.isThrownBy(() -> repository.findBy(QPerson.person.firstname.ne("foo"), FluentQuery.FetchableFluentQuery::one));
|
||||
|
||||
Person one = repository.findBy(QPerson.person.firstname.eq("tyrion"), FluentQuery.FetchableFluentQuery::oneValue);
|
||||
|
||||
assertThat(one).isEqualTo(TYRION);
|
||||
}
|
||||
|
||||
@Test // GH-397
|
||||
void findByShouldReturnFirstWithProjection() {
|
||||
|
||||
PersonProjection interfaceProjection = repository.findBy(QPerson.person.firstname.eq("tyrion"),
|
||||
it -> it.as(PersonProjection.class).firstValue());
|
||||
assertThat(interfaceProjection.getFirstname()).isEqualTo("tyrion");
|
||||
|
||||
PersonDto dto = repository.findBy(QPerson.person.firstname.eq("tyrion"), it -> it.as(PersonDto.class).firstValue());
|
||||
assertThat(dto.getFirstname()).isEqualTo("tyrion");
|
||||
}
|
||||
|
||||
@Test // GH-397
|
||||
void findByShouldReturnOneWithProjection() {
|
||||
|
||||
PersonProjection interfaceProjection = repository.findBy(QPerson.person.firstname.eq("tyrion"),
|
||||
it -> it.as(PersonProjection.class).oneValue());
|
||||
assertThat(interfaceProjection.getFirstname()).isEqualTo("tyrion");
|
||||
|
||||
PersonDto dto = repository.findBy(QPerson.person.firstname.eq("tyrion"), it -> it.as(PersonDto.class).oneValue());
|
||||
assertThat(dto.getFirstname()).isEqualTo("tyrion");
|
||||
}
|
||||
|
||||
@Test // GH-397
|
||||
void findByShouldReturnAll() {
|
||||
|
||||
List<Person> all = repository.findBy(QPerson.person.firstname.eq("tyrion"), FluentQuery.FetchableFluentQuery::all);
|
||||
|
||||
assertThat(all).contains(TYRION);
|
||||
}
|
||||
|
||||
@Test // GH-397
|
||||
void findByShouldReturnAllSorted() {
|
||||
|
||||
List<Person> all = repository.findBy(QPerson.person.firstname.ne("foo"),
|
||||
q -> q.sortBy(Sort.by(Direction.ASC, "firstname")).all());
|
||||
|
||||
assertThat(all).containsSequence(CERSEI, JAIME, TYRION);
|
||||
|
||||
all = repository.findBy(QPerson.person.firstname.ne("foo"),
|
||||
q -> q.sortBy(Sort.by(Direction.DESC, "firstname")).all());
|
||||
|
||||
assertThat(all).containsSequence(TYRION, JAIME, CERSEI);
|
||||
}
|
||||
|
||||
@Test // GH-397
|
||||
void findByShouldReturnAllWithProjection() {
|
||||
|
||||
Stream<PersonProjection> all = repository.findBy(QPerson.person.firstname.eq("tyrion"),
|
||||
q -> q.as(PersonProjection.class).stream());
|
||||
|
||||
assertThat(all).hasOnlyElementsOfType(PersonProjection.class);
|
||||
}
|
||||
|
||||
@Test // GH-397
|
||||
void findByShouldReturnPage() {
|
||||
|
||||
Page<PersonProjection> page = repository.findBy(QPerson.person.firstname.ne("foo"),
|
||||
it -> it.as(PersonProjection.class).page(PageRequest.of(0, 1, Sort.by("firstname"))));
|
||||
|
||||
assertThat(page.getContent().get(0).getFirstname()).isEqualTo("cersei");
|
||||
assertThat(page.getTotalPages()).isEqualTo(3);
|
||||
|
||||
Page<PersonProjection> nextPage = repository.findBy(QPerson.person.firstname.ne("foo"),
|
||||
it -> it.as(PersonProjection.class).page(page.nextPageable()));
|
||||
|
||||
assertThat(nextPage.getContent().get(0).getFirstname()).isEqualTo("jaime");
|
||||
assertThat(nextPage.getTotalPages()).isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test // GH-397
|
||||
void findByShouldReturnStream() {
|
||||
|
||||
List<Person> all = repository.findBy(QPerson.person.firstname.eq("tyrion"), FluentQuery.FetchableFluentQuery::all);
|
||||
|
||||
assertThat(all).contains(TYRION);
|
||||
}
|
||||
|
||||
@Test // GH-397
|
||||
void findByShouldReturnStreamWithProjection() {
|
||||
|
||||
Stream<PersonProjection> all = repository.findBy(QPerson.person.firstname.eq("tyrion"),
|
||||
q -> q.as(PersonProjection.class).stream());
|
||||
|
||||
assertThat(all).hasOnlyElementsOfType(PersonProjection.class);
|
||||
}
|
||||
|
||||
@Test // GH-397
|
||||
void findByShouldReturnCount() {
|
||||
|
||||
long count = repository.findBy(QPerson.person.firstname.ne("foo"), FluentQuery.FetchableFluentQuery::count);
|
||||
|
||||
assertThat(count).isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test // GH-397
|
||||
void findByShouldReturnExists() {
|
||||
|
||||
boolean exists = repository.findBy(QPerson.person.firstname.eq("tyrion"), FluentQuery.FetchableFluentQuery::exists);
|
||||
assertThat(exists).isTrue();
|
||||
|
||||
exists = repository.findBy(QPerson.person.firstname.eq("foo"), FluentQuery.FetchableFluentQuery::exists);
|
||||
assertThat(exists).isFalse();
|
||||
}
|
||||
|
||||
interface PersonProjection {
|
||||
String getFirstname();
|
||||
}
|
||||
|
||||
@Data
|
||||
static class PersonDto {
|
||||
|
||||
String firstname;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.map.SimpleKeyValueRepositoryUnitTests#getRepository(org.springframework.data.keyvalue.repository.support.KeyValueRepositoryFactory)
|
||||
Reference in New Issue
Block a user