From 73c29742682791632026b676c1e4b088c470b8df Mon Sep 17 00:00:00 2001 From: Moritz Becker Date: Thu, 12 Dec 2024 22:41:05 +0100 Subject: [PATCH] [#1965] Use regular CriteriaBuilder instead of PaginatedCriteriaBuilder for unpaged Spring Data JPA repository invocations --- README.md | 2 +- .../query/PartTreeBlazePersistenceQuery.java | 28 +- .../query/PartTreeBlazePersistenceQuery.java | 28 +- .../query/PartTreeBlazePersistenceQuery.java | 28 +- .../query/PartTreeBlazePersistenceQuery.java | 29 +- .../query/PartTreeBlazePersistenceQuery.java | 29 +- .../query/PartTreeBlazePersistenceQuery.java | 29 +- .../query/PartTreeBlazePersistenceQuery.java | 29 +- .../query/PartTreeBlazePersistenceQuery.java | 29 +- .../query/PartTreeBlazePersistenceQuery.java | 29 +- .../query/PartTreeBlazePersistenceQuery.java | 29 +- .../query/PartTreeBlazePersistenceQuery.java | 29 +- .../data/base/query/ParameterBinder.java | 5 +- .../AbstractEntityViewAwareRepository.java | 22 +- .../data/base/query/ParameterBinder.java | 5 +- .../AbstractEntityViewAwareRepository.java | 22 +- .../spring/data/base/PageableUtil.java | 32 + ...AbstractPartTreeBlazePersistenceQuery.java | 7 +- .../data/base/query/ParameterBinder.java | 6 +- .../AbstractEntityViewAwareRepository.java | 23 +- .../testsuite/webmvc/entity/Document.java | 4 +- .../testsuite/webmvc/entity/Identifiable.java | 11 + .../data/testsuite/webmvc/entity/Person.java | 4 +- ...terizedReadOnlyDocumentRepositoryTest.java | 964 ++++++++++++++++++ .../ReadOnlyDocumentRepositoryTest.java | 919 +---------------- .../ReadOnlyDocumentRepository.java | 2 + .../webmvc/view/DocumentUpdateView.java | 4 +- .../testsuite/webmvc/view/DocumentView.java | 4 +- .../webmvc/view/PersonUpdateView.java | 4 +- .../testsuite/webmvc/view/PersonView.java | 4 +- 30 files changed, 1204 insertions(+), 1156 deletions(-) create mode 100644 integration/spring-data/base/src/main/java/com/blazebit/persistence/spring/data/base/PageableUtil.java create mode 100644 integration/spring-data/testsuite/webmvc/src/main/java/com/blazebit/persistence/spring/data/testsuite/webmvc/entity/Identifiable.java create mode 100644 integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/ParameterizedReadOnlyDocumentRepositoryTest.java diff --git a/README.md b/README.md index 9fdd1c55dd..6785604ddd 100644 --- a/README.md +++ b/README.md @@ -526,7 +526,7 @@ For executing tests against a database on a dedicated host you might want to spe ## Testing with Jakarta Persistence provider To build everything use `mvn -pl core/testsuite-jakarta-runner clean install -am -P "hibernate-6.2,jakarta,h2,spring-data-2.6.x,deltaspike-1.9" -DskipTests` -and to run tests use ` mvn -pl core/testsuite-jakarta-runner clean install -P "hibernate-6.2,jakarta,h2,spring-data-2.6.x,deltaspike-1.9" "-Dtest=com.blazebit.persistence.testsuite.SetOperationTest#testUnionAllOrderBySubqueryLimit"`. +and to run tests use `mvn -pl core/testsuite-jakarta-runner clean install -P "hibernate-6.2,jakarta,h2,spring-data-2.6.x,deltaspike-1.9" "-Dtest=com.blazebit.persistence.testsuite.SetOperationTest#testUnionAllOrderBySubqueryLimit"`. ## Switching JPA provider profiles in IntelliJ diff --git a/integration/spring-data/1.x/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java b/integration/spring-data/1.x/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java index 03f418f822..33c20208bf 100644 --- a/integration/spring-data/1.x/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java +++ b/integration/spring-data/1.x/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java @@ -23,7 +23,6 @@ import org.springframework.data.jpa.repository.query.JpaEntityGraph; import org.springframework.data.jpa.repository.query.JpaQueryExecution; import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.data.repository.query.Parameters; import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.parser.PartTree; @@ -59,9 +58,9 @@ protected ParameterMetadataProvider createParameterMetadataProvider(CriteriaBuil @Override protected JpaQueryExecution getExecution() { if (getQueryMethod().isSliceQuery()) { - return new PartTreeBlazePersistenceQuery.SlicedExecution(getQueryMethod().getParameters()); + return new PartTreeBlazePersistenceQuery.SlicedExecution(); } else if (getQueryMethod().isPageQuery()) { - return new PartTreeBlazePersistenceQuery.PagedExecution(getQueryMethod().getParameters()); + return new PartTreeBlazePersistenceQuery.PagedExecution(); } else if (isDelete()) { return new PartTreeBlazePersistenceQuery.DeleteExecution(getEntityManager()); } else if (isExists()) { @@ -93,18 +92,12 @@ protected Object doExecute(AbstractJpaQuery repositoryQuery, Object[] values) { */ private static class SlicedExecution extends JpaQueryExecution { - private final Parameters parameters; - - public SlicedExecution(Parameters parameters) { - this.parameters = parameters; - } - @Override @SuppressWarnings("unchecked") protected Object doExecute(AbstractJpaQuery repositoryQuery, Object[] values) { Query paginatedCriteriaBuilder = ((PartTreeBlazePersistenceQuery) repositoryQuery).createPaginatedQuery(values, false); PagedList resultList = (PagedList) paginatedCriteriaBuilder.getResultList(); - ParameterAccessor accessor = new ParametersParameterAccessor(parameters, values); + ParameterAccessor accessor = new ParametersParameterAccessor(repositoryQuery.getQueryMethod().getParameters(), values); Pageable pageable = accessor.getPageable(); return new KeysetAwareSliceImpl<>(resultList, pageable); @@ -119,20 +112,19 @@ protected Object doExecute(AbstractJpaQuery repositoryQuery, Object[] values) { */ private static class PagedExecution extends JpaQueryExecution { - private final Parameters parameters; - - public PagedExecution(Parameters parameters) { - this.parameters = parameters; - } - @Override @SuppressWarnings("unchecked") protected Object doExecute(AbstractJpaQuery repositoryQuery, Object[] values) { + ParameterAccessor accessor = new ParametersParameterAccessor(repositoryQuery.getQueryMethod().getParameters(), values); + Pageable pageable = accessor.getPageable(); + if (pageable == null) { + List unpagedResult = ((PartTreeBlazePersistenceQuery) repositoryQuery).createQuery(values).getResultList(); + return new KeysetAwarePageImpl<>(unpagedResult); + } + Query paginatedCriteriaBuilder = ((PartTreeBlazePersistenceQuery) repositoryQuery).createPaginatedQuery(values, true); PagedList resultList = (PagedList) paginatedCriteriaBuilder.getResultList(); Long total = resultList.getTotalSize(); - ParameterAccessor accessor = new ParametersParameterAccessor(parameters, values); - Pageable pageable = accessor.getPageable(); if (total.equals(0L)) { return new KeysetAwarePageImpl<>(Collections.emptyList(), total, null, pageable); diff --git a/integration/spring-data/2.0/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java b/integration/spring-data/2.0/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java index f52cc0021f..3eba93f2e7 100644 --- a/integration/spring-data/2.0/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java +++ b/integration/spring-data/2.0/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java @@ -23,7 +23,6 @@ import org.springframework.data.jpa.repository.query.JpaEntityGraph; import org.springframework.data.jpa.repository.query.JpaQueryExecution; import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.data.repository.query.Parameters; import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.parser.PartTree; @@ -59,9 +58,9 @@ protected ParameterMetadataProvider createParameterMetadataProvider(CriteriaBuil @Override protected JpaQueryExecution getExecution() { if (getQueryMethod().isSliceQuery()) { - return new PartTreeBlazePersistenceQuery.SlicedExecution(getQueryMethod().getParameters()); + return new PartTreeBlazePersistenceQuery.SlicedExecution(); } else if (getQueryMethod().isPageQuery()) { - return new PartTreeBlazePersistenceQuery.PagedExecution(getQueryMethod().getParameters()); + return new PartTreeBlazePersistenceQuery.PagedExecution(); } else if (isDelete()) { return new PartTreeBlazePersistenceQuery.DeleteExecution(getEntityManager()); } else if (isExists()) { @@ -93,18 +92,12 @@ protected Object doExecute(AbstractJpaQuery repositoryQuery, Object[] values) { */ private static class SlicedExecution extends JpaQueryExecution { - private final Parameters parameters; - - public SlicedExecution(Parameters parameters) { - this.parameters = parameters; - } - @Override @SuppressWarnings("unchecked") protected Object doExecute(AbstractJpaQuery repositoryQuery, Object[] values) { Query paginatedCriteriaBuilder = ((PartTreeBlazePersistenceQuery) repositoryQuery).createPaginatedQuery(values, false); PagedList resultList = (PagedList) paginatedCriteriaBuilder.getResultList(); - ParameterAccessor accessor = new ParametersParameterAccessor(parameters, values); + ParameterAccessor accessor = new ParametersParameterAccessor(repositoryQuery.getQueryMethod().getParameters(), values); Pageable pageable = accessor.getPageable(); return new KeysetAwareSliceImpl<>(resultList, pageable); @@ -119,20 +112,19 @@ protected Object doExecute(AbstractJpaQuery repositoryQuery, Object[] values) { */ private static class PagedExecution extends JpaQueryExecution { - private final Parameters parameters; - - public PagedExecution(Parameters parameters) { - this.parameters = parameters; - } - @Override @SuppressWarnings("unchecked") protected Object doExecute(AbstractJpaQuery repositoryQuery, Object[] values) { + ParameterAccessor accessor = new ParametersParameterAccessor(repositoryQuery.getQueryMethod().getParameters(), values); + Pageable pageable = accessor.getPageable(); + if (pageable.isUnpaged()) { + List unpagedResult = ((PartTreeBlazePersistenceQuery) repositoryQuery).createQuery(values).getResultList(); + return new KeysetAwarePageImpl<>(unpagedResult); + } + Query paginatedCriteriaBuilder = ((PartTreeBlazePersistenceQuery) repositoryQuery).createPaginatedQuery(values, true); PagedList resultList = (PagedList) paginatedCriteriaBuilder.getResultList(); Long total = resultList.getTotalSize(); - ParameterAccessor accessor = new ParametersParameterAccessor(parameters, values); - Pageable pageable = accessor.getPageable(); if (total.equals(0L)) { return new KeysetAwarePageImpl<>(Collections.emptyList(), total, null, pageable); diff --git a/integration/spring-data/2.1/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java b/integration/spring-data/2.1/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java index be1b14780f..8f791c0d84 100644 --- a/integration/spring-data/2.1/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java +++ b/integration/spring-data/2.1/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java @@ -24,7 +24,6 @@ import org.springframework.data.jpa.repository.query.JpaEntityGraph; import org.springframework.data.jpa.repository.query.JpaQueryExecution; import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.data.repository.query.Parameters; import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.parser.PartTree; @@ -60,9 +59,9 @@ protected ParameterMetadataProvider createParameterMetadataProvider(CriteriaBuil @Override protected JpaQueryExecution getExecution() { if (getQueryMethod().isSliceQuery()) { - return new PartTreeBlazePersistenceQuery.SlicedExecution(getQueryMethod().getParameters()); + return new PartTreeBlazePersistenceQuery.SlicedExecution(); } else if (getQueryMethod().isPageQuery()) { - return new PartTreeBlazePersistenceQuery.PagedExecution(getQueryMethod().getParameters()); + return new PartTreeBlazePersistenceQuery.PagedExecution(); } else if (isDelete()) { return new PartTreeBlazePersistenceQuery.DeleteExecution(getEntityManager()); } else if (isExists()) { @@ -94,18 +93,12 @@ protected Object doExecute(AbstractJpaQuery repositoryQuery, Object[] values) { */ private static class SlicedExecution extends JpaQueryExecution { - private final Parameters parameters; - - public SlicedExecution(Parameters parameters) { - this.parameters = parameters; - } - @Override @SuppressWarnings("unchecked") protected Object doExecute(AbstractJpaQuery repositoryQuery, Object[] values) { Query paginatedCriteriaBuilder = ((PartTreeBlazePersistenceQuery) repositoryQuery).createPaginatedQuery(values, false); PagedList resultList = (PagedList) paginatedCriteriaBuilder.getResultList(); - ParameterAccessor accessor = new ParametersParameterAccessor(parameters, values); + ParameterAccessor accessor = new ParametersParameterAccessor(repositoryQuery.getQueryMethod().getParameters(), values); Pageable pageable = accessor.getPageable(); return new KeysetAwareSliceImpl<>(resultList, pageable); @@ -120,20 +113,19 @@ protected Object doExecute(AbstractJpaQuery repositoryQuery, Object[] values) { */ private static class PagedExecution extends JpaQueryExecution { - private final Parameters parameters; - - public PagedExecution(Parameters parameters) { - this.parameters = parameters; - } - @Override @SuppressWarnings("unchecked") protected Object doExecute(AbstractJpaQuery repositoryQuery, Object[] values) { + ParameterAccessor accessor = new ParametersParameterAccessor(repositoryQuery.getQueryMethod().getParameters(), values); + Pageable pageable = accessor.getPageable(); + if (pageable.isUnpaged()) { + List unpagedResult = ((PartTreeBlazePersistenceQuery) repositoryQuery).createQuery(values).getResultList(); + return new KeysetAwarePageImpl<>(unpagedResult); + } + Query paginatedCriteriaBuilder = ((PartTreeBlazePersistenceQuery) repositoryQuery).createPaginatedQuery(values, true); PagedList resultList = (PagedList) paginatedCriteriaBuilder.getResultList(); Long total = resultList.getTotalSize(); - ParameterAccessor accessor = new ParametersParameterAccessor(parameters, values); - Pageable pageable = accessor.getPageable(); if (total.equals(0L)) { return new KeysetAwarePageImpl<>(Collections.emptyList(), total, null, pageable); diff --git a/integration/spring-data/2.2/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java b/integration/spring-data/2.2/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java index 8bf734fbe9..8bf325c026 100644 --- a/integration/spring-data/2.2/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java +++ b/integration/spring-data/2.2/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java @@ -24,8 +24,6 @@ import org.springframework.data.jpa.repository.query.JpaEntityGraph; import org.springframework.data.jpa.repository.query.JpaParametersParameterAccessor; import org.springframework.data.jpa.repository.query.JpaQueryExecution; -import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.data.repository.query.Parameters; import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.parser.PartTree; @@ -61,9 +59,9 @@ protected ParameterMetadataProvider createParameterMetadataProvider(CriteriaBuil @Override protected JpaQueryExecution getExecution() { if (getQueryMethod().isSliceQuery()) { - return new PartTreeBlazePersistenceQuery.SlicedExecution(getQueryMethod().getParameters()); + return new PartTreeBlazePersistenceQuery.SlicedExecution(); } else if (getQueryMethod().isPageQuery()) { - return new PartTreeBlazePersistenceQuery.PagedExecution(getQueryMethod().getParameters()); + return new PartTreeBlazePersistenceQuery.PagedExecution(); } else if (isDelete()) { return new PartTreeBlazePersistenceQuery.DeleteExecution(getEntityManager()); } else if (isExists()) { @@ -95,19 +93,12 @@ protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParame */ private static class SlicedExecution extends JpaQueryExecution { - private final Parameters parameters; - - public SlicedExecution(Parameters parameters) { - this.parameters = parameters; - } - @Override @SuppressWarnings("unchecked") protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParameterAccessor jpaParametersParameterAccessor) { Query paginatedCriteriaBuilder = ((PartTreeBlazePersistenceQuery) repositoryQuery).createPaginatedQuery(jpaParametersParameterAccessor.getValues(), false); PagedList resultList = (PagedList) paginatedCriteriaBuilder.getResultList(); - ParameterAccessor accessor = new ParametersParameterAccessor(parameters, jpaParametersParameterAccessor.getValues()); - Pageable pageable = accessor.getPageable(); + Pageable pageable = jpaParametersParameterAccessor.getPageable(); return new KeysetAwareSliceImpl<>(resultList, pageable); } @@ -121,20 +112,18 @@ protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParame */ private static class PagedExecution extends JpaQueryExecution { - private final Parameters parameters; - - public PagedExecution(Parameters parameters) { - this.parameters = parameters; - } - @Override @SuppressWarnings("unchecked") protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParameterAccessor jpaParametersParameterAccessor) { + Pageable pageable = jpaParametersParameterAccessor.getPageable(); + if (pageable.isUnpaged()) { + List unpagedResult = ((PartTreeBlazePersistenceQuery) repositoryQuery).createQuery(jpaParametersParameterAccessor).getResultList(); + return new KeysetAwarePageImpl<>(unpagedResult); + } + Query paginatedCriteriaBuilder = ((PartTreeBlazePersistenceQuery) repositoryQuery).createPaginatedQuery(jpaParametersParameterAccessor.getValues(), true); PagedList resultList = (PagedList) paginatedCriteriaBuilder.getResultList(); Long total = resultList.getTotalSize(); - ParameterAccessor accessor = new ParametersParameterAccessor(parameters, jpaParametersParameterAccessor.getValues()); - Pageable pageable = accessor.getPageable(); if (total.equals(0L)) { return new KeysetAwarePageImpl<>(Collections.emptyList(), total, null, pageable); diff --git a/integration/spring-data/2.3/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java b/integration/spring-data/2.3/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java index 8bf734fbe9..8bf325c026 100644 --- a/integration/spring-data/2.3/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java +++ b/integration/spring-data/2.3/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java @@ -24,8 +24,6 @@ import org.springframework.data.jpa.repository.query.JpaEntityGraph; import org.springframework.data.jpa.repository.query.JpaParametersParameterAccessor; import org.springframework.data.jpa.repository.query.JpaQueryExecution; -import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.data.repository.query.Parameters; import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.parser.PartTree; @@ -61,9 +59,9 @@ protected ParameterMetadataProvider createParameterMetadataProvider(CriteriaBuil @Override protected JpaQueryExecution getExecution() { if (getQueryMethod().isSliceQuery()) { - return new PartTreeBlazePersistenceQuery.SlicedExecution(getQueryMethod().getParameters()); + return new PartTreeBlazePersistenceQuery.SlicedExecution(); } else if (getQueryMethod().isPageQuery()) { - return new PartTreeBlazePersistenceQuery.PagedExecution(getQueryMethod().getParameters()); + return new PartTreeBlazePersistenceQuery.PagedExecution(); } else if (isDelete()) { return new PartTreeBlazePersistenceQuery.DeleteExecution(getEntityManager()); } else if (isExists()) { @@ -95,19 +93,12 @@ protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParame */ private static class SlicedExecution extends JpaQueryExecution { - private final Parameters parameters; - - public SlicedExecution(Parameters parameters) { - this.parameters = parameters; - } - @Override @SuppressWarnings("unchecked") protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParameterAccessor jpaParametersParameterAccessor) { Query paginatedCriteriaBuilder = ((PartTreeBlazePersistenceQuery) repositoryQuery).createPaginatedQuery(jpaParametersParameterAccessor.getValues(), false); PagedList resultList = (PagedList) paginatedCriteriaBuilder.getResultList(); - ParameterAccessor accessor = new ParametersParameterAccessor(parameters, jpaParametersParameterAccessor.getValues()); - Pageable pageable = accessor.getPageable(); + Pageable pageable = jpaParametersParameterAccessor.getPageable(); return new KeysetAwareSliceImpl<>(resultList, pageable); } @@ -121,20 +112,18 @@ protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParame */ private static class PagedExecution extends JpaQueryExecution { - private final Parameters parameters; - - public PagedExecution(Parameters parameters) { - this.parameters = parameters; - } - @Override @SuppressWarnings("unchecked") protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParameterAccessor jpaParametersParameterAccessor) { + Pageable pageable = jpaParametersParameterAccessor.getPageable(); + if (pageable.isUnpaged()) { + List unpagedResult = ((PartTreeBlazePersistenceQuery) repositoryQuery).createQuery(jpaParametersParameterAccessor).getResultList(); + return new KeysetAwarePageImpl<>(unpagedResult); + } + Query paginatedCriteriaBuilder = ((PartTreeBlazePersistenceQuery) repositoryQuery).createPaginatedQuery(jpaParametersParameterAccessor.getValues(), true); PagedList resultList = (PagedList) paginatedCriteriaBuilder.getResultList(); Long total = resultList.getTotalSize(); - ParameterAccessor accessor = new ParametersParameterAccessor(parameters, jpaParametersParameterAccessor.getValues()); - Pageable pageable = accessor.getPageable(); if (total.equals(0L)) { return new KeysetAwarePageImpl<>(Collections.emptyList(), total, null, pageable); diff --git a/integration/spring-data/2.4/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java b/integration/spring-data/2.4/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java index e8adbb21e0..e10b825d60 100644 --- a/integration/spring-data/2.4/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java +++ b/integration/spring-data/2.4/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java @@ -25,8 +25,6 @@ import org.springframework.data.jpa.repository.query.JpaParametersParameterAccessor; import org.springframework.data.jpa.repository.query.JpaQueryExecution; import org.springframework.data.jpa.repository.support.QueryHints; -import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.data.repository.query.Parameters; import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.parser.PartTree; @@ -63,9 +61,9 @@ protected ParameterMetadataProvider createParameterMetadataProvider(CriteriaBuil @Override protected JpaQueryExecution getExecution() { if (getQueryMethod().isSliceQuery()) { - return new PartTreeBlazePersistenceQuery.SlicedExecution(getQueryMethod().getParameters()); + return new PartTreeBlazePersistenceQuery.SlicedExecution(); } else if (getQueryMethod().isPageQuery()) { - return new PartTreeBlazePersistenceQuery.PagedExecution(getQueryMethod().getParameters()); + return new PartTreeBlazePersistenceQuery.PagedExecution(); } else if (isDelete()) { return new PartTreeBlazePersistenceQuery.DeleteExecution(getEntityManager()); } else if (isExists()) { @@ -97,19 +95,12 @@ protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParame */ private static class SlicedExecution extends JpaQueryExecution { - private final Parameters parameters; - - public SlicedExecution(Parameters parameters) { - this.parameters = parameters; - } - @Override @SuppressWarnings("unchecked") protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParameterAccessor jpaParametersParameterAccessor) { Query paginatedCriteriaBuilder = ((PartTreeBlazePersistenceQuery) repositoryQuery).createPaginatedQuery(jpaParametersParameterAccessor.getValues(), false); PagedList resultList = (PagedList) paginatedCriteriaBuilder.getResultList(); - ParameterAccessor accessor = new ParametersParameterAccessor(parameters, jpaParametersParameterAccessor.getValues()); - Pageable pageable = accessor.getPageable(); + Pageable pageable = jpaParametersParameterAccessor.getPageable(); return new KeysetAwareSliceImpl<>(resultList, pageable); } @@ -123,20 +114,18 @@ protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParame */ private static class PagedExecution extends JpaQueryExecution { - private final Parameters parameters; - - public PagedExecution(Parameters parameters) { - this.parameters = parameters; - } - @Override @SuppressWarnings("unchecked") protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParameterAccessor jpaParametersParameterAccessor) { + Pageable pageable = jpaParametersParameterAccessor.getPageable(); + if (pageable.isUnpaged()) { + List unpagedResult = ((PartTreeBlazePersistenceQuery) repositoryQuery).createQuery(jpaParametersParameterAccessor).getResultList(); + return new KeysetAwarePageImpl<>(unpagedResult); + } + Query paginatedCriteriaBuilder = ((PartTreeBlazePersistenceQuery) repositoryQuery).createPaginatedQuery(jpaParametersParameterAccessor.getValues(), true); PagedList resultList = (PagedList) paginatedCriteriaBuilder.getResultList(); Long total = resultList.getTotalSize(); - ParameterAccessor accessor = new ParametersParameterAccessor(parameters, jpaParametersParameterAccessor.getValues()); - Pageable pageable = accessor.getPageable(); if (total.equals(0L)) { return new KeysetAwarePageImpl<>(Collections.emptyList(), total, null, pageable); diff --git a/integration/spring-data/2.5/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java b/integration/spring-data/2.5/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java index e8adbb21e0..e10b825d60 100644 --- a/integration/spring-data/2.5/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java +++ b/integration/spring-data/2.5/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java @@ -25,8 +25,6 @@ import org.springframework.data.jpa.repository.query.JpaParametersParameterAccessor; import org.springframework.data.jpa.repository.query.JpaQueryExecution; import org.springframework.data.jpa.repository.support.QueryHints; -import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.data.repository.query.Parameters; import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.parser.PartTree; @@ -63,9 +61,9 @@ protected ParameterMetadataProvider createParameterMetadataProvider(CriteriaBuil @Override protected JpaQueryExecution getExecution() { if (getQueryMethod().isSliceQuery()) { - return new PartTreeBlazePersistenceQuery.SlicedExecution(getQueryMethod().getParameters()); + return new PartTreeBlazePersistenceQuery.SlicedExecution(); } else if (getQueryMethod().isPageQuery()) { - return new PartTreeBlazePersistenceQuery.PagedExecution(getQueryMethod().getParameters()); + return new PartTreeBlazePersistenceQuery.PagedExecution(); } else if (isDelete()) { return new PartTreeBlazePersistenceQuery.DeleteExecution(getEntityManager()); } else if (isExists()) { @@ -97,19 +95,12 @@ protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParame */ private static class SlicedExecution extends JpaQueryExecution { - private final Parameters parameters; - - public SlicedExecution(Parameters parameters) { - this.parameters = parameters; - } - @Override @SuppressWarnings("unchecked") protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParameterAccessor jpaParametersParameterAccessor) { Query paginatedCriteriaBuilder = ((PartTreeBlazePersistenceQuery) repositoryQuery).createPaginatedQuery(jpaParametersParameterAccessor.getValues(), false); PagedList resultList = (PagedList) paginatedCriteriaBuilder.getResultList(); - ParameterAccessor accessor = new ParametersParameterAccessor(parameters, jpaParametersParameterAccessor.getValues()); - Pageable pageable = accessor.getPageable(); + Pageable pageable = jpaParametersParameterAccessor.getPageable(); return new KeysetAwareSliceImpl<>(resultList, pageable); } @@ -123,20 +114,18 @@ protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParame */ private static class PagedExecution extends JpaQueryExecution { - private final Parameters parameters; - - public PagedExecution(Parameters parameters) { - this.parameters = parameters; - } - @Override @SuppressWarnings("unchecked") protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParameterAccessor jpaParametersParameterAccessor) { + Pageable pageable = jpaParametersParameterAccessor.getPageable(); + if (pageable.isUnpaged()) { + List unpagedResult = ((PartTreeBlazePersistenceQuery) repositoryQuery).createQuery(jpaParametersParameterAccessor).getResultList(); + return new KeysetAwarePageImpl<>(unpagedResult); + } + Query paginatedCriteriaBuilder = ((PartTreeBlazePersistenceQuery) repositoryQuery).createPaginatedQuery(jpaParametersParameterAccessor.getValues(), true); PagedList resultList = (PagedList) paginatedCriteriaBuilder.getResultList(); Long total = resultList.getTotalSize(); - ParameterAccessor accessor = new ParametersParameterAccessor(parameters, jpaParametersParameterAccessor.getValues()); - Pageable pageable = accessor.getPageable(); if (total.equals(0L)) { return new KeysetAwarePageImpl<>(Collections.emptyList(), total, null, pageable); diff --git a/integration/spring-data/2.6/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java b/integration/spring-data/2.6/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java index e8adbb21e0..e10b825d60 100644 --- a/integration/spring-data/2.6/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java +++ b/integration/spring-data/2.6/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java @@ -25,8 +25,6 @@ import org.springframework.data.jpa.repository.query.JpaParametersParameterAccessor; import org.springframework.data.jpa.repository.query.JpaQueryExecution; import org.springframework.data.jpa.repository.support.QueryHints; -import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.data.repository.query.Parameters; import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.parser.PartTree; @@ -63,9 +61,9 @@ protected ParameterMetadataProvider createParameterMetadataProvider(CriteriaBuil @Override protected JpaQueryExecution getExecution() { if (getQueryMethod().isSliceQuery()) { - return new PartTreeBlazePersistenceQuery.SlicedExecution(getQueryMethod().getParameters()); + return new PartTreeBlazePersistenceQuery.SlicedExecution(); } else if (getQueryMethod().isPageQuery()) { - return new PartTreeBlazePersistenceQuery.PagedExecution(getQueryMethod().getParameters()); + return new PartTreeBlazePersistenceQuery.PagedExecution(); } else if (isDelete()) { return new PartTreeBlazePersistenceQuery.DeleteExecution(getEntityManager()); } else if (isExists()) { @@ -97,19 +95,12 @@ protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParame */ private static class SlicedExecution extends JpaQueryExecution { - private final Parameters parameters; - - public SlicedExecution(Parameters parameters) { - this.parameters = parameters; - } - @Override @SuppressWarnings("unchecked") protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParameterAccessor jpaParametersParameterAccessor) { Query paginatedCriteriaBuilder = ((PartTreeBlazePersistenceQuery) repositoryQuery).createPaginatedQuery(jpaParametersParameterAccessor.getValues(), false); PagedList resultList = (PagedList) paginatedCriteriaBuilder.getResultList(); - ParameterAccessor accessor = new ParametersParameterAccessor(parameters, jpaParametersParameterAccessor.getValues()); - Pageable pageable = accessor.getPageable(); + Pageable pageable = jpaParametersParameterAccessor.getPageable(); return new KeysetAwareSliceImpl<>(resultList, pageable); } @@ -123,20 +114,18 @@ protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParame */ private static class PagedExecution extends JpaQueryExecution { - private final Parameters parameters; - - public PagedExecution(Parameters parameters) { - this.parameters = parameters; - } - @Override @SuppressWarnings("unchecked") protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParameterAccessor jpaParametersParameterAccessor) { + Pageable pageable = jpaParametersParameterAccessor.getPageable(); + if (pageable.isUnpaged()) { + List unpagedResult = ((PartTreeBlazePersistenceQuery) repositoryQuery).createQuery(jpaParametersParameterAccessor).getResultList(); + return new KeysetAwarePageImpl<>(unpagedResult); + } + Query paginatedCriteriaBuilder = ((PartTreeBlazePersistenceQuery) repositoryQuery).createPaginatedQuery(jpaParametersParameterAccessor.getValues(), true); PagedList resultList = (PagedList) paginatedCriteriaBuilder.getResultList(); Long total = resultList.getTotalSize(); - ParameterAccessor accessor = new ParametersParameterAccessor(parameters, jpaParametersParameterAccessor.getValues()); - Pageable pageable = accessor.getPageable(); if (total.equals(0L)) { return new KeysetAwarePageImpl<>(Collections.emptyList(), total, null, pageable); diff --git a/integration/spring-data/2.7/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java b/integration/spring-data/2.7/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java index e8adbb21e0..e10b825d60 100644 --- a/integration/spring-data/2.7/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java +++ b/integration/spring-data/2.7/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java @@ -25,8 +25,6 @@ import org.springframework.data.jpa.repository.query.JpaParametersParameterAccessor; import org.springframework.data.jpa.repository.query.JpaQueryExecution; import org.springframework.data.jpa.repository.support.QueryHints; -import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.data.repository.query.Parameters; import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.parser.PartTree; @@ -63,9 +61,9 @@ protected ParameterMetadataProvider createParameterMetadataProvider(CriteriaBuil @Override protected JpaQueryExecution getExecution() { if (getQueryMethod().isSliceQuery()) { - return new PartTreeBlazePersistenceQuery.SlicedExecution(getQueryMethod().getParameters()); + return new PartTreeBlazePersistenceQuery.SlicedExecution(); } else if (getQueryMethod().isPageQuery()) { - return new PartTreeBlazePersistenceQuery.PagedExecution(getQueryMethod().getParameters()); + return new PartTreeBlazePersistenceQuery.PagedExecution(); } else if (isDelete()) { return new PartTreeBlazePersistenceQuery.DeleteExecution(getEntityManager()); } else if (isExists()) { @@ -97,19 +95,12 @@ protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParame */ private static class SlicedExecution extends JpaQueryExecution { - private final Parameters parameters; - - public SlicedExecution(Parameters parameters) { - this.parameters = parameters; - } - @Override @SuppressWarnings("unchecked") protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParameterAccessor jpaParametersParameterAccessor) { Query paginatedCriteriaBuilder = ((PartTreeBlazePersistenceQuery) repositoryQuery).createPaginatedQuery(jpaParametersParameterAccessor.getValues(), false); PagedList resultList = (PagedList) paginatedCriteriaBuilder.getResultList(); - ParameterAccessor accessor = new ParametersParameterAccessor(parameters, jpaParametersParameterAccessor.getValues()); - Pageable pageable = accessor.getPageable(); + Pageable pageable = jpaParametersParameterAccessor.getPageable(); return new KeysetAwareSliceImpl<>(resultList, pageable); } @@ -123,20 +114,18 @@ protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParame */ private static class PagedExecution extends JpaQueryExecution { - private final Parameters parameters; - - public PagedExecution(Parameters parameters) { - this.parameters = parameters; - } - @Override @SuppressWarnings("unchecked") protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParameterAccessor jpaParametersParameterAccessor) { + Pageable pageable = jpaParametersParameterAccessor.getPageable(); + if (pageable.isUnpaged()) { + List unpagedResult = ((PartTreeBlazePersistenceQuery) repositoryQuery).createQuery(jpaParametersParameterAccessor).getResultList(); + return new KeysetAwarePageImpl<>(unpagedResult); + } + Query paginatedCriteriaBuilder = ((PartTreeBlazePersistenceQuery) repositoryQuery).createPaginatedQuery(jpaParametersParameterAccessor.getValues(), true); PagedList resultList = (PagedList) paginatedCriteriaBuilder.getResultList(); Long total = resultList.getTotalSize(); - ParameterAccessor accessor = new ParametersParameterAccessor(parameters, jpaParametersParameterAccessor.getValues()); - Pageable pageable = accessor.getPageable(); if (total.equals(0L)) { return new KeysetAwarePageImpl<>(Collections.emptyList(), total, null, pageable); diff --git a/integration/spring-data/3.1/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java b/integration/spring-data/3.1/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java index 18dbe0922a..5e8899946a 100644 --- a/integration/spring-data/3.1/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java +++ b/integration/spring-data/3.1/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java @@ -25,8 +25,6 @@ import org.springframework.data.jpa.repository.query.JpaParametersParameterAccessor; import org.springframework.data.jpa.repository.query.JpaQueryExecution; import org.springframework.data.jpa.repository.support.QueryHints; -import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.data.repository.query.Parameters; import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.parser.PartTree; import jakarta.persistence.EntityManager; @@ -64,9 +62,9 @@ protected ParameterMetadataProvider createParameterMetadataProvider(CriteriaBuil @Override protected JpaQueryExecution getExecution() { if (getQueryMethod().isSliceQuery()) { - return new PartTreeBlazePersistenceQuery.SlicedExecution(getQueryMethod().getParameters()); + return new PartTreeBlazePersistenceQuery.SlicedExecution(); } else if (getQueryMethod().isPageQuery()) { - return new PartTreeBlazePersistenceQuery.PagedExecution(getQueryMethod().getParameters()); + return new PartTreeBlazePersistenceQuery.PagedExecution(); } else if (isDelete()) { return new PartTreeBlazePersistenceQuery.DeleteExecution(getEntityManager()); } else if (isExists()) { @@ -98,19 +96,12 @@ protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParame */ private static class SlicedExecution extends JpaQueryExecution { - private final Parameters parameters; - - public SlicedExecution(Parameters parameters) { - this.parameters = parameters; - } - @Override @SuppressWarnings("unchecked") protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParameterAccessor jpaParametersParameterAccessor) { Query paginatedCriteriaBuilder = ((PartTreeBlazePersistenceQuery) repositoryQuery).createPaginatedQuery(jpaParametersParameterAccessor.getValues(), false); PagedList resultList = (PagedList) paginatedCriteriaBuilder.getResultList(); - ParameterAccessor accessor = new ParametersParameterAccessor(parameters, jpaParametersParameterAccessor.getValues()); - Pageable pageable = accessor.getPageable(); + Pageable pageable = jpaParametersParameterAccessor.getPageable(); return new KeysetAwareSliceImpl<>(resultList, pageable); } @@ -124,20 +115,18 @@ protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParame */ private static class PagedExecution extends JpaQueryExecution { - private final Parameters parameters; - - public PagedExecution(Parameters parameters) { - this.parameters = parameters; - } - @Override @SuppressWarnings("unchecked") protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParameterAccessor jpaParametersParameterAccessor) { + Pageable pageable = jpaParametersParameterAccessor.getPageable(); + if (pageable.isUnpaged()) { + List unpagedResult = ((PartTreeBlazePersistenceQuery) repositoryQuery).createQuery(jpaParametersParameterAccessor).getResultList(); + return new KeysetAwarePageImpl<>(unpagedResult); + } + Query paginatedCriteriaBuilder = ((PartTreeBlazePersistenceQuery) repositoryQuery).createPaginatedQuery(jpaParametersParameterAccessor.getValues(), true); PagedList resultList = (PagedList) paginatedCriteriaBuilder.getResultList(); Long total = resultList.getTotalSize(); - ParameterAccessor accessor = new ParametersParameterAccessor(parameters, jpaParametersParameterAccessor.getValues()); - Pageable pageable = accessor.getPageable(); if (total.equals(0L)) { return new KeysetAwarePageImpl<>(Collections.emptyList(), total, null, pageable); diff --git a/integration/spring-data/3.3/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java b/integration/spring-data/3.3/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java index 18dbe0922a..5e8899946a 100644 --- a/integration/spring-data/3.3/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java +++ b/integration/spring-data/3.3/src/main/java/com/blazebit/persistence/spring/data/impl/query/PartTreeBlazePersistenceQuery.java @@ -25,8 +25,6 @@ import org.springframework.data.jpa.repository.query.JpaParametersParameterAccessor; import org.springframework.data.jpa.repository.query.JpaQueryExecution; import org.springframework.data.jpa.repository.support.QueryHints; -import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.data.repository.query.Parameters; import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.parser.PartTree; import jakarta.persistence.EntityManager; @@ -64,9 +62,9 @@ protected ParameterMetadataProvider createParameterMetadataProvider(CriteriaBuil @Override protected JpaQueryExecution getExecution() { if (getQueryMethod().isSliceQuery()) { - return new PartTreeBlazePersistenceQuery.SlicedExecution(getQueryMethod().getParameters()); + return new PartTreeBlazePersistenceQuery.SlicedExecution(); } else if (getQueryMethod().isPageQuery()) { - return new PartTreeBlazePersistenceQuery.PagedExecution(getQueryMethod().getParameters()); + return new PartTreeBlazePersistenceQuery.PagedExecution(); } else if (isDelete()) { return new PartTreeBlazePersistenceQuery.DeleteExecution(getEntityManager()); } else if (isExists()) { @@ -98,19 +96,12 @@ protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParame */ private static class SlicedExecution extends JpaQueryExecution { - private final Parameters parameters; - - public SlicedExecution(Parameters parameters) { - this.parameters = parameters; - } - @Override @SuppressWarnings("unchecked") protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParameterAccessor jpaParametersParameterAccessor) { Query paginatedCriteriaBuilder = ((PartTreeBlazePersistenceQuery) repositoryQuery).createPaginatedQuery(jpaParametersParameterAccessor.getValues(), false); PagedList resultList = (PagedList) paginatedCriteriaBuilder.getResultList(); - ParameterAccessor accessor = new ParametersParameterAccessor(parameters, jpaParametersParameterAccessor.getValues()); - Pageable pageable = accessor.getPageable(); + Pageable pageable = jpaParametersParameterAccessor.getPageable(); return new KeysetAwareSliceImpl<>(resultList, pageable); } @@ -124,20 +115,18 @@ protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParame */ private static class PagedExecution extends JpaQueryExecution { - private final Parameters parameters; - - public PagedExecution(Parameters parameters) { - this.parameters = parameters; - } - @Override @SuppressWarnings("unchecked") protected Object doExecute(AbstractJpaQuery repositoryQuery, JpaParametersParameterAccessor jpaParametersParameterAccessor) { + Pageable pageable = jpaParametersParameterAccessor.getPageable(); + if (pageable.isUnpaged()) { + List unpagedResult = ((PartTreeBlazePersistenceQuery) repositoryQuery).createQuery(jpaParametersParameterAccessor).getResultList(); + return new KeysetAwarePageImpl<>(unpagedResult); + } + Query paginatedCriteriaBuilder = ((PartTreeBlazePersistenceQuery) repositoryQuery).createPaginatedQuery(jpaParametersParameterAccessor.getValues(), true); PagedList resultList = (PagedList) paginatedCriteriaBuilder.getResultList(); Long total = resultList.getTotalSize(); - ParameterAccessor accessor = new ParametersParameterAccessor(parameters, jpaParametersParameterAccessor.getValues()); - Pageable pageable = accessor.getPageable(); if (total.equals(0L)) { return new KeysetAwarePageImpl<>(Collections.emptyList(), total, null, pageable); diff --git a/integration/spring-data/base-3.1/src/main/java/com/blazebit/persistence/spring/data/base/query/ParameterBinder.java b/integration/spring-data/base-3.1/src/main/java/com/blazebit/persistence/spring/data/base/query/ParameterBinder.java index 003f2c85f8..ee44b8aaef 100644 --- a/integration/spring-data/base-3.1/src/main/java/com/blazebit/persistence/spring/data/base/query/ParameterBinder.java +++ b/integration/spring-data/base-3.1/src/main/java/com/blazebit/persistence/spring/data/base/query/ParameterBinder.java @@ -165,12 +165,13 @@ private Query bindAndPrepare(Query query, Parameters parameters) { Query result = bind(query); - if (!parameters.hasPageableParameter() || getPageable() == null) { + Pageable pageable; + if (!parameters.hasPageableParameter() || (pageable = getPageable()).isUnpaged()) { return result; } result.setFirstResult(getOffset()); - result.setMaxResults(getPageable().getPageSize()); + result.setMaxResults(pageable.getPageSize()); return result; } diff --git a/integration/spring-data/base-3.1/src/main/java/com/blazebit/persistence/spring/data/base/repository/AbstractEntityViewAwareRepository.java b/integration/spring-data/base-3.1/src/main/java/com/blazebit/persistence/spring/data/base/repository/AbstractEntityViewAwareRepository.java index 9d7f67257f..4c18983fdf 100644 --- a/integration/spring-data/base-3.1/src/main/java/com/blazebit/persistence/spring/data/base/repository/AbstractEntityViewAwareRepository.java +++ b/integration/spring-data/base-3.1/src/main/java/com/blazebit/persistence/spring/data/base/repository/AbstractEntityViewAwareRepository.java @@ -76,18 +76,6 @@ public abstract class AbstractEntityViewAwareRepository Page findAll(Example example, Pageable pageable) { Class probeType = example.getProbeType(); TypedQuery query = getQuery(new ExampleSpecification<>(example, escapeCharacter), probeType, pageable); - return pageable == null || pageable == UNPAGED ? new KeysetAwarePageImpl<>(query.getResultList()) : new KeysetAwarePageImpl<>((PagedList) query.getResultList(), pageable); + return pageable == null || pageable.isUnpaged() ? new KeysetAwarePageImpl<>(query.getResultList()) : new KeysetAwarePageImpl<>((PagedList) query.getResultList(), pageable); } public List findAll(Sort sort) { @@ -351,7 +339,7 @@ public List findAll(Sort sort) { } public Page findAll(Pageable pageable) { - if (pageable == null || pageable == UNPAGED) { + if (pageable == null || pageable.isUnpaged()) { return (Page) new PageImpl<>(findAll()); } @@ -561,7 +549,7 @@ public List findAll(Specification spec) { public Page findAll(Specification spec, Pageable pageable) { TypedQuery query = getQuery(spec, pageable); - if (pageable == null || pageable == UNPAGED) { + if (pageable == null || pageable.isUnpaged()) { return new KeysetAwarePageImpl<>(query.getResultList()); } PagedList resultList = (PagedList) query.getResultList(); @@ -623,7 +611,7 @@ protected TypedQuery getQuery(Specification spec, Class d TypedQuery query; if (entityViewClass == null) { - if (pageable == null || pageable == UNPAGED) { + if (pageable == null || pageable.isUnpaged()) { query = (TypedQuery) cb.getQuery(); } else { PaginatedCriteriaBuilder paginatedCriteriaBuilder; @@ -644,7 +632,7 @@ protected TypedQuery getQuery(Specification spec, Class d query = (TypedQuery) paginatedCriteriaBuilder.getQuery(); } } else { - if (pageable == null || pageable == UNPAGED) { + if (pageable == null || pageable.isUnpaged()) { EntityViewSetting> setting = EntityViewSetting.create(entityViewClass); CriteriaBuilder fqb = evm.applySetting(setting, cb); if (sort != null) { diff --git a/integration/spring-data/base-3.3/src/main/java/com/blazebit/persistence/spring/data/base/query/ParameterBinder.java b/integration/spring-data/base-3.3/src/main/java/com/blazebit/persistence/spring/data/base/query/ParameterBinder.java index 003f2c85f8..ee44b8aaef 100644 --- a/integration/spring-data/base-3.3/src/main/java/com/blazebit/persistence/spring/data/base/query/ParameterBinder.java +++ b/integration/spring-data/base-3.3/src/main/java/com/blazebit/persistence/spring/data/base/query/ParameterBinder.java @@ -165,12 +165,13 @@ private Query bindAndPrepare(Query query, Parameters parameters) { Query result = bind(query); - if (!parameters.hasPageableParameter() || getPageable() == null) { + Pageable pageable; + if (!parameters.hasPageableParameter() || (pageable = getPageable()).isUnpaged()) { return result; } result.setFirstResult(getOffset()); - result.setMaxResults(getPageable().getPageSize()); + result.setMaxResults(pageable.getPageSize()); return result; } diff --git a/integration/spring-data/base-3.3/src/main/java/com/blazebit/persistence/spring/data/base/repository/AbstractEntityViewAwareRepository.java b/integration/spring-data/base-3.3/src/main/java/com/blazebit/persistence/spring/data/base/repository/AbstractEntityViewAwareRepository.java index 9d7f67257f..4c18983fdf 100644 --- a/integration/spring-data/base-3.3/src/main/java/com/blazebit/persistence/spring/data/base/repository/AbstractEntityViewAwareRepository.java +++ b/integration/spring-data/base-3.3/src/main/java/com/blazebit/persistence/spring/data/base/repository/AbstractEntityViewAwareRepository.java @@ -76,18 +76,6 @@ public abstract class AbstractEntityViewAwareRepository Page findAll(Example example, Pageable pageable) { Class probeType = example.getProbeType(); TypedQuery query = getQuery(new ExampleSpecification<>(example, escapeCharacter), probeType, pageable); - return pageable == null || pageable == UNPAGED ? new KeysetAwarePageImpl<>(query.getResultList()) : new KeysetAwarePageImpl<>((PagedList) query.getResultList(), pageable); + return pageable == null || pageable.isUnpaged() ? new KeysetAwarePageImpl<>(query.getResultList()) : new KeysetAwarePageImpl<>((PagedList) query.getResultList(), pageable); } public List findAll(Sort sort) { @@ -351,7 +339,7 @@ public List findAll(Sort sort) { } public Page findAll(Pageable pageable) { - if (pageable == null || pageable == UNPAGED) { + if (pageable == null || pageable.isUnpaged()) { return (Page) new PageImpl<>(findAll()); } @@ -561,7 +549,7 @@ public List findAll(Specification spec) { public Page findAll(Specification spec, Pageable pageable) { TypedQuery query = getQuery(spec, pageable); - if (pageable == null || pageable == UNPAGED) { + if (pageable == null || pageable.isUnpaged()) { return new KeysetAwarePageImpl<>(query.getResultList()); } PagedList resultList = (PagedList) query.getResultList(); @@ -623,7 +611,7 @@ protected TypedQuery getQuery(Specification spec, Class d TypedQuery query; if (entityViewClass == null) { - if (pageable == null || pageable == UNPAGED) { + if (pageable == null || pageable.isUnpaged()) { query = (TypedQuery) cb.getQuery(); } else { PaginatedCriteriaBuilder paginatedCriteriaBuilder; @@ -644,7 +632,7 @@ protected TypedQuery getQuery(Specification spec, Class d query = (TypedQuery) paginatedCriteriaBuilder.getQuery(); } } else { - if (pageable == null || pageable == UNPAGED) { + if (pageable == null || pageable.isUnpaged()) { EntityViewSetting> setting = EntityViewSetting.create(entityViewClass); CriteriaBuilder fqb = evm.applySetting(setting, cb); if (sort != null) { diff --git a/integration/spring-data/base/src/main/java/com/blazebit/persistence/spring/data/base/PageableUtil.java b/integration/spring-data/base/src/main/java/com/blazebit/persistence/spring/data/base/PageableUtil.java new file mode 100644 index 0000000000..72dd40d60e --- /dev/null +++ b/integration/spring-data/base/src/main/java/com/blazebit/persistence/spring/data/base/PageableUtil.java @@ -0,0 +1,32 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Blazebit + */ + +package com.blazebit.persistence.spring.data.base; + +import java.lang.reflect.Method; +import org.springframework.data.domain.Pageable; + +public final class PageableUtil { + + private static final Pageable UNPAGED; + + static { + Pageable unpaged = null; + try { + Method unpagedMethod = Class.forName("org.springframework.data.domain.Pageable").getMethod("unpaged"); + unpaged = (Pageable) unpagedMethod.invoke(null); + } catch (Exception e) { + // ignore + } + UNPAGED = unpaged; + } + + private PageableUtil() { + } + + public static boolean isUnpaged(Pageable pageable) { + return pageable == null || pageable == UNPAGED; + } +} diff --git a/integration/spring-data/base/src/main/java/com/blazebit/persistence/spring/data/base/query/AbstractPartTreeBlazePersistenceQuery.java b/integration/spring-data/base/src/main/java/com/blazebit/persistence/spring/data/base/query/AbstractPartTreeBlazePersistenceQuery.java index 20f250878a..a9dc057d05 100644 --- a/integration/spring-data/base/src/main/java/com/blazebit/persistence/spring/data/base/query/AbstractPartTreeBlazePersistenceQuery.java +++ b/integration/spring-data/base/src/main/java/com/blazebit/persistence/spring/data/base/query/AbstractPartTreeBlazePersistenceQuery.java @@ -367,8 +367,11 @@ protected void processSort(FullQueryBuilder cb, Object[] values, Class int pageableIndex; if ((sortIndex = parameters.getSortIndex()) >= 0 && (sort = (Sort) values[sortIndex]) != null) { EntityViewSortUtil.applySort(evm, entityViewClass, cb, sort); - } else if ((pageableIndex = parameters.getPageableIndex()) >= 0 && (sort = ((Pageable) values[pageableIndex]).getSort()) != null) { - EntityViewSortUtil.applySort(evm, entityViewClass, cb, sort); + } else if ((pageableIndex = parameters.getPageableIndex()) >= 0) { + Pageable pageable = (Pageable) values[pageableIndex]; + if (pageable != null && (sort = pageable.getSort()) != null) { + EntityViewSortUtil.applySort(evm, entityViewClass, cb, sort); + } } for (Map.Entry attributeSorterEntry : evsAttributeSorter.entrySet()) { attributeSorterEntry.getValue().apply((OrderByBuilder) cb, attributeSorterEntry.getKey()); diff --git a/integration/spring-data/base/src/main/java/com/blazebit/persistence/spring/data/base/query/ParameterBinder.java b/integration/spring-data/base/src/main/java/com/blazebit/persistence/spring/data/base/query/ParameterBinder.java index 727a97747c..72cdc87430 100644 --- a/integration/spring-data/base/src/main/java/com/blazebit/persistence/spring/data/base/query/ParameterBinder.java +++ b/integration/spring-data/base/src/main/java/com/blazebit/persistence/spring/data/base/query/ParameterBinder.java @@ -15,6 +15,7 @@ */ package com.blazebit.persistence.spring.data.base.query; +import com.blazebit.persistence.spring.data.base.PageableUtil; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.jpa.repository.query.AbstractJpaQuery; @@ -163,12 +164,13 @@ private Query bindAndPrepare(Query query, Parameters parameters) { Query result = bind(query); - if (!parameters.hasPageableParameter() || getPageable() == null) { + Pageable pageable; + if (!parameters.hasPageableParameter() || PageableUtil.isUnpaged(pageable = getPageable())) { return result; } result.setFirstResult(getOffset()); - result.setMaxResults(getPageable().getPageSize()); + result.setMaxResults(pageable.getPageSize()); return result; } diff --git a/integration/spring-data/base/src/main/java/com/blazebit/persistence/spring/data/base/repository/AbstractEntityViewAwareRepository.java b/integration/spring-data/base/src/main/java/com/blazebit/persistence/spring/data/base/repository/AbstractEntityViewAwareRepository.java index 6f2192de1b..8e6dfd6252 100644 --- a/integration/spring-data/base/src/main/java/com/blazebit/persistence/spring/data/base/repository/AbstractEntityViewAwareRepository.java +++ b/integration/spring-data/base/src/main/java/com/blazebit/persistence/spring/data/base/repository/AbstractEntityViewAwareRepository.java @@ -15,6 +15,7 @@ import com.blazebit.persistence.parser.EntityMetamodel; import com.blazebit.persistence.spi.ExtendedManagedType; import com.blazebit.persistence.spring.data.base.EntityViewSortUtil; +import com.blazebit.persistence.spring.data.base.PageableUtil; import com.blazebit.persistence.spring.data.base.query.KeysetAwarePageImpl; import com.blazebit.persistence.spring.data.repository.KeysetPageable; import com.blazebit.persistence.view.EntityViewManager; @@ -69,18 +70,6 @@ public abstract class AbstractEntityViewAwareRepository Page findAll(Example example, Pageable pageable) { Class probeType = example.getProbeType(); TypedQuery query = getQuery(new ExampleSpecification<>(example, escapeCharacter), probeType, pageable); - return pageable == null || pageable == UNPAGED ? new KeysetAwarePageImpl<>(query.getResultList()) : new KeysetAwarePageImpl<>((PagedList) query.getResultList(), pageable); + return PageableUtil.isUnpaged(pageable) ? new KeysetAwarePageImpl<>(query.getResultList()) : new KeysetAwarePageImpl<>((PagedList) query.getResultList(), pageable); } public List findAll(Sort sort) { @@ -339,7 +328,7 @@ public List findAll(Sort sort) { } public Page findAll(Pageable pageable) { - if (pageable == null || pageable == UNPAGED) { + if (PageableUtil.isUnpaged(pageable)) { return (Page) new PageImpl<>(findAll()); } @@ -502,7 +491,7 @@ public List findAll(Specification spec) { public Page findAll(Specification spec, Pageable pageable) { TypedQuery query = getQuery(spec, pageable); - if (pageable == null || pageable == UNPAGED) { + if (PageableUtil.isUnpaged(pageable)) { return new KeysetAwarePageImpl<>(query.getResultList()); } PagedList resultList = (PagedList) query.getResultList(); @@ -564,7 +553,7 @@ protected TypedQuery getQuery(Specification spec, Class d TypedQuery query; if (entityViewClass == null) { - if (pageable == null || pageable == UNPAGED) { + if (PageableUtil.isUnpaged(pageable)) { query = (TypedQuery) cb.getQuery(); } else { PaginatedCriteriaBuilder paginatedCriteriaBuilder; @@ -585,7 +574,7 @@ protected TypedQuery getQuery(Specification spec, Class d query = (TypedQuery) paginatedCriteriaBuilder.getQuery(); } } else { - if (pageable == null || pageable == UNPAGED) { + if (PageableUtil.isUnpaged(pageable)) { EntityViewSetting> setting = EntityViewSetting.create(entityViewClass); CriteriaBuilder fqb = evm.applySetting(setting, cb); if (sort != null) { diff --git a/integration/spring-data/testsuite/webmvc/src/main/java/com/blazebit/persistence/spring/data/testsuite/webmvc/entity/Document.java b/integration/spring-data/testsuite/webmvc/src/main/java/com/blazebit/persistence/spring/data/testsuite/webmvc/entity/Document.java index 32ab322e3b..949b3f9986 100644 --- a/integration/spring-data/testsuite/webmvc/src/main/java/com/blazebit/persistence/spring/data/testsuite/webmvc/entity/Document.java +++ b/integration/spring-data/testsuite/webmvc/src/main/java/com/blazebit/persistence/spring/data/testsuite/webmvc/entity/Document.java @@ -14,7 +14,6 @@ import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; -import java.io.Serializable; /** * @author Moritz Becker @@ -25,7 +24,7 @@ @NamedQuery(name = "findIdOfD1", query = "select d.id from Document d where d.name = 'D1'") }) @Entity -public class Document implements Serializable { +public class Document implements Identifiable { private Long id; private String name; @@ -43,6 +42,7 @@ public Document(String name) { @Id @GeneratedValue + @Override public Long getId() { return id; } diff --git a/integration/spring-data/testsuite/webmvc/src/main/java/com/blazebit/persistence/spring/data/testsuite/webmvc/entity/Identifiable.java b/integration/spring-data/testsuite/webmvc/src/main/java/com/blazebit/persistence/spring/data/testsuite/webmvc/entity/Identifiable.java new file mode 100644 index 0000000000..85db4bb352 --- /dev/null +++ b/integration/spring-data/testsuite/webmvc/src/main/java/com/blazebit/persistence/spring/data/testsuite/webmvc/entity/Identifiable.java @@ -0,0 +1,11 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Blazebit + */ + +package com.blazebit.persistence.spring.data.testsuite.webmvc.entity; + +public interface Identifiable { + + T getId(); +} diff --git a/integration/spring-data/testsuite/webmvc/src/main/java/com/blazebit/persistence/spring/data/testsuite/webmvc/entity/Person.java b/integration/spring-data/testsuite/webmvc/src/main/java/com/blazebit/persistence/spring/data/testsuite/webmvc/entity/Person.java index 7b9c174dc6..9d2d0128c4 100644 --- a/integration/spring-data/testsuite/webmvc/src/main/java/com/blazebit/persistence/spring/data/testsuite/webmvc/entity/Person.java +++ b/integration/spring-data/testsuite/webmvc/src/main/java/com/blazebit/persistence/spring/data/testsuite/webmvc/entity/Person.java @@ -9,7 +9,6 @@ import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.OneToMany; -import java.io.Serializable; import java.util.HashSet; import java.util.Set; import java.util.UUID; @@ -20,7 +19,7 @@ * @since 1.5.0 */ @Entity -public class Person implements Serializable { +public class Person implements Identifiable { private static final long serialVersionUID = 1L; private String id; @@ -38,6 +37,7 @@ public Person(String name) { } @Id + @Override public String getId() { return id; } diff --git a/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/ParameterizedReadOnlyDocumentRepositoryTest.java b/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/ParameterizedReadOnlyDocumentRepositoryTest.java new file mode 100644 index 0000000000..cfe8680af2 --- /dev/null +++ b/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/ParameterizedReadOnlyDocumentRepositoryTest.java @@ -0,0 +1,964 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Blazebit + */ + +package com.blazebit.persistence.spring.data.testsuite.webmvc; + +import com.blazebit.persistence.integration.view.spring.EnableEntityViews; +import com.blazebit.persistence.spring.data.repository.BlazeSpecification; +import com.blazebit.persistence.spring.data.repository.EntityViewSettingProcessor; +import com.blazebit.persistence.spring.data.repository.KeysetAwarePage; +import com.blazebit.persistence.spring.data.repository.KeysetPageRequest; +import com.blazebit.persistence.spring.data.repository.config.EnableBlazeRepositories; +import com.blazebit.persistence.spring.data.testsuite.webmvc.accessor.DocumentAccessor; +import com.blazebit.persistence.spring.data.testsuite.webmvc.accessor.DocumentAccessors; +import com.blazebit.persistence.spring.data.testsuite.webmvc.config.SystemPropertyBasedActiveProfilesResolver; +import com.blazebit.persistence.spring.data.testsuite.webmvc.entity.Document; +import com.blazebit.persistence.spring.data.testsuite.webmvc.entity.MyEnum; +import com.blazebit.persistence.spring.data.testsuite.webmvc.entity.Person; +import com.blazebit.persistence.spring.data.testsuite.webmvc.repository.ReadOnlyDocumentEntityRepository; +import com.blazebit.persistence.spring.data.testsuite.webmvc.repository.ReadOnlyDocumentRepository; +import com.blazebit.persistence.spring.data.testsuite.webmvc.repository.ReadOnlyDocumentViewRepository; +import com.blazebit.persistence.spring.data.testsuite.webmvc.tx.TransactionalWorkService; +import com.blazebit.persistence.spring.data.testsuite.webmvc.tx.TxWork; +import com.blazebit.persistence.spring.data.testsuite.webmvc.view.DocumentView; +import com.blazebit.persistence.testsuite.base.jpa.category.NoDB2; +import com.blazebit.persistence.testsuite.base.jpa.category.NoDatanucleus; +import com.blazebit.persistence.testsuite.base.jpa.category.NoEclipselink; +import com.blazebit.persistence.testsuite.base.jpa.category.NoFirebird; +import com.blazebit.persistence.testsuite.base.jpa.category.NoHibernate42; +import com.blazebit.persistence.testsuite.base.jpa.category.NoMySQL; +import com.blazebit.persistence.testsuite.base.jpa.category.NoOracle; +import com.blazebit.persistence.testsuite.base.jpa.category.NoPostgreSQL; +import com.blazebit.persistence.testsuite.base.jpa.category.NoSQLite; +import com.blazebit.persistence.view.EntityViewManager; +import com.blazebit.persistence.view.EntityViewSetting; +import com.blazebit.persistence.view.Sorters; + +import java.util.stream.Collectors; +import org.junit.Assert; +import org.junit.Assume; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.AutowireCapableBeanFactory; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.FilterType; +import org.springframework.context.annotation.ImportResource; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; + +import javax.persistence.EntityManager; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +/** + * @author Moritz Becker + * @since 1.2.0 + */ +@RunWith(Parameterized.class) +@ContextConfiguration(classes = ParameterizedReadOnlyDocumentRepositoryTest.TestConfig.class) +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) +public class ParameterizedReadOnlyDocumentRepositoryTest extends AbstractSpringTest { + + private static final Pageable UNPAGED; + + static { + Pageable unpaged = null; + try { + Method unpagedMethod = Class.forName("org.springframework.data.domain.Pageable").getMethod("unpaged"); + unpaged = (Pageable) unpagedMethod.invoke(null); + } catch (Exception e) { + // ignore + } + UNPAGED = unpaged; + } + + @Parameterized.Parameters + public static Iterable createParameters() { + return Arrays.asList(ReadOnlyDocumentViewRepository.class, ReadOnlyDocumentEntityRepository.class); + } + + private final Class> repositoryClass; + + @Autowired + private AutowireCapableBeanFactory autowireCapableBeanFactory; + + @Autowired + private TransactionalWorkService transactionalWorkService; + + private ReadOnlyDocumentRepository readOnlyDocumentRepository; + + public ParameterizedReadOnlyDocumentRepositoryTest(Class> repositoryClass) { + this.repositoryClass = repositoryClass; + } + + @Before + public void initRepository() { + readOnlyDocumentRepository = autowireCapableBeanFactory.getBean(repositoryClass); + } + + // NOTE: EclipseLink and DataNucleus seem to have a problem with the way Spring Data makes use of entity graphs, although it just uses the JPA APIs + // Hibernate 4.2 doesn't support the JPA 2.1 APIs that introduced entity graphs + @Test + @Category({ NoHibernate42.class, NoEclipselink.class, NoDatanucleus.class }) + public void testFindD1EntityGraph() { + // Given + final Document d1 = createDocument("D1"); + final Document d2 = createDocument("D2"); + + // When + Document d = readOnlyDocumentRepository.findD1EntityGraph(); + + // Then + assertEquals(d1.getId(), d.getId()); + } + + @Test + public void testFindD1NamedQuery() { + // Given + final Document d1 = createDocument("D1"); + final Document d2 = createDocument("D2"); + + // When + Document d = readOnlyDocumentRepository.findD1NamedQuery(); + + // Then + assertEquals(d1.getId(), d.getId()); + } + + @Test + // We don't want to deal with the different casing requirements for table names in the various DBs so we only run + // this test for H2. + // DataNucleus is not able to create entities from native query result sets. + @Category({NoDatanucleus.class, NoPostgreSQL.class, NoOracle.class, NoMySQL.class, NoSQLite.class, NoFirebird.class, NoDB2.class}) + public void testFindD1Native() { + // Given + final Document d1 = createDocument("D1"); + final Document d2 = createDocument("D2"); + + // When + Document d = readOnlyDocumentRepository.findD1Native(); + + // Then + assertEquals(d1.getId(), d.getId()); + } + + @Test + public void testFindD1Projection() { + // Given + final Document d1 = createDocument("D1"); + final Document d2 = createDocument("D2"); + + // When + Long id = readOnlyDocumentRepository.findD1Projection(); + + // Then + assertEquals(d1.getId(), id); + } + + @Test + public void testFindD1NamedQueryProjection() { + // Given + final Document d1 = createDocument("D1"); + final Document d2 = createDocument("D2"); + + // When + Long id = readOnlyDocumentRepository.findD1NamedQueryProjection(); + + // Then + assertEquals(d1.getId(), id); + } + + @Test + // We don't want to deal with the different casing requirements for table names in the various DBs so we only run + // this test for H2. + @Category({NoPostgreSQL.class, NoOracle.class, NoMySQL.class, NoSQLite.class, NoFirebird.class, NoDB2.class}) + public void testFindD1NativeProjection() { + // Given + final Document d1 = createDocument("D1"); + final Document d2 = createDocument("D2"); + + // When + Long id = readOnlyDocumentRepository.findD1NativeProjection(); + + // Then + assertEquals(d1.getId(), id); + } + + @Test + public void testFindOne() { + // Given + final Document d1 = createDocument("D1"); + final Document d2 = createDocument("D2"); + + // When + DocumentAccessor result1 = DocumentAccessors.of(readOnlyDocumentRepository.findOne(d1.getId())); + DocumentAccessor result2 = DocumentAccessors.of(readOnlyDocumentRepository.findOne(d2.getId())); + + // Then + assertEquals(d1.getId(), result1.getId()); + assertNotNull(result1); + + assertEquals(d2.getId(), result2.getId()); + assertNotNull(result2); + } + + @Test + public void testExists(){ + // Given + final Document d1 = createDocument("D1"); + + // When + boolean existsP1 = readOnlyDocumentRepository.exists(d1.getId()); + + // Then + assertTrue(existsP1); + } + + @Test + public void testFindAll() { + // Given + final Person p1 = createPerson("P1"); + final Document d1 = createDocument("D1", p1); + final Document d2 = createDocument("D2", p1); + + // When + Iterable actual = DocumentAccessors.of(readOnlyDocumentRepository.findAll()); + List actualIds = getIdsFromViews(actual); + + // Then + assertEquals(2, actualIds.size()); + assertTrue(actualIds.contains(d1.getId())); + assertTrue(actualIds.contains(d2.getId())); + } + + @Test + public void testFindAllByIds() { + // ignored with EclipseLink due to IN collection rendering bug + Assume.assumeFalse(isEntityRepository() && isEclipseLink()); + // Given + final Document d1 = createDocument("D1"); + final Document d2 = createDocument("D2"); + + // When + Iterable actual = DocumentAccessors.of(readOnlyDocumentRepository.findAll(Arrays.asList(d1.getId(), d2.getId()))); + List actualIds = getIdsFromViews(actual); + + // Then + assertEquals(2, actualIds.size()); + assertTrue(actualIds.contains(d1.getId())); + assertTrue(actualIds.contains(d2.getId())); + } + + @Test + public void testCount() { + // Given + final Document d1 = createDocument("D1"); + final Document d2 = createDocument("D2"); + + // When + long count = readOnlyDocumentRepository.count(); + + // Then + assertEquals(2, count); + } + + @Test + public void testFindByName() { + // Given + final Document d1 = createDocument("D1"); + + // When + List result = DocumentAccessors.of(readOnlyDocumentRepository.findByName(d1.getName())); + + // Then + assertEquals(1, result.size()); + assertEquals(d1.getId(), result.get(0).getId()); + } + + @Test + public void testFindByDescription() { + // Given + final Document d1 = createDocument("D1", "test", 0, null); + + // When + List elements = readOnlyDocumentRepository.findByDescription(d1.getDescription()); + + // Then + assertEquals(1, elements.size()); + if (repositoryClass == ReadOnlyDocumentViewRepository.class) { + assertTrue(elements.get(0) instanceof Document); + } else { + assertTrue(elements.get(0) instanceof DocumentView); + } + List result = DocumentAccessors.of(elements); + assertEquals(d1.getId(), result.get(0).getId()); + } + + @Test + public void testFindByNameAndAgeOrDescription() { + // Given + final String name = "D1"; + final Document d1 = createDocument(name, "desc1", 12, null); + final Document d2 = createDocument(name, "desc2", 13, null); + final Document d3 = createDocument(name, "desc3", 14, null); + + // When + List actual = DocumentAccessors.of(readOnlyDocumentRepository.findByNameAndAgeOrDescription(name, 12, "desc2")); + List actualIds = getIdsFromViews(actual); + + // Then + assertEquals(2, actual.size()); + assertTrue(actualIds.contains(d1.getId())); + assertTrue(actualIds.contains(d2.getId())); + } + + @Test + public void testFindByNameIn() { + // ignored with EclipseLink due to IN collection rendering bug + Assume.assumeFalse(isEntityRepository() && isEclipseLink()); + // Given + final Document d1 = createDocument("d1"); + final Document d2 = createDocument("d2"); + final Document d3 = createDocument("d3"); + + // When + List actual = DocumentAccessors.of(readOnlyDocumentRepository.findByNameIn(d2.getName(), d3.getName())); + List actualIds = getIdsFromViews(actual); + + // Then + assertEquals(2, actual.size()); + assertTrue(actualIds.contains(d2.getId())); + assertTrue(actualIds.contains(d3.getId())); + } + + @Test + public void testFindByNameInPaginated() { + // ignored with EclipseLink due to IN collection rendering bug + Assume.assumeFalse(isEntityRepository() && isEclipseLink()); + // Given + final Document d1 = createDocument("d1"); + final Document d2 = createDocument("d2"); + final Document d3 = createDocument("d3"); + + // When + Page actual = DocumentAccessors.of(readOnlyDocumentRepository.findByNameInOrderById(new PageRequest(0, 1), d2.getName(), d3.getName())); + List actualIds = getIdsFromViews(actual); + + // Then + assertEquals(2, actual.getTotalPages()); + assertEquals(0, actual.getNumber()); + assertEquals(1, actual.getNumberOfElements()); + assertEquals(1, actual.getSize()); + assertTrue(actualIds.contains(d2.getId())); + + actual = DocumentAccessors.of(readOnlyDocumentRepository.findByNameInOrderById(actual.nextPageable(), d2.getName(), d3.getName())); + actualIds = getIdsFromViews(actual); + assertEquals(2, actual.getTotalPages()); + assertEquals(1, actual.getNumber()); + assertEquals(1, actual.getNumberOfElements()); + assertEquals(1, actual.getSize()); + assertTrue(actualIds.contains(d3.getId())); + } + + @Test + public void testFindByNameInKeysetPaginated() { + // ignored with EclipseLink due to IN collection rendering bug + Assume.assumeFalse(isEntityRepository() && isEclipseLink()); + // Given + final Document d1 = createDocument("d1"); + final Document d2 = createDocument("d2"); + final Document d3 = createDocument("d3"); + + // When + KeysetAwarePage actual = DocumentAccessors.of(readOnlyDocumentRepository.findByNameIn(new KeysetPageRequest(null, Sort.asc("id"), 0, 1), d2.getName(), d3.getName())); + List actualIds = getIdsFromViews(actual); + + // Then + assertEquals(2, actual.getTotalPages()); + assertEquals(0, actual.getNumber()); + assertEquals(1, actual.getNumberOfElements()); + assertEquals(1, actual.getSize()); + assertTrue(actualIds.contains(d2.getId())); + + actual = DocumentAccessors.of(readOnlyDocumentRepository.findByNameIn(actual.nextPageable(), d2.getName(), d3.getName())); + actualIds = getIdsFromViews(actual); + assertEquals(2, actual.getTotalPages()); + assertEquals(1, actual.getNumber()); + assertEquals(1, actual.getNumberOfElements()); + assertEquals(1, actual.getSize()); + assertTrue(actualIds.contains(d3.getId())); + } + + @Test + public void testFindByNameLikeOrderByAgeAsc() { + // Given + final Document d1 = createDocument("d1", null, 2l, null); + final Document d2 = createDocument("d2", null, 1l, null); + + // When + List actual = DocumentAccessors.of(readOnlyDocumentRepository.findByNameLikeOrderByAgeAsc("d%")); + + // Then + assertEquals(2, actual.size()); + assertEquals(d2.getId(), actual.get(0).getId()); + assertEquals(d1.getId(), actual.get(1).getId()); + } + + @Test + public void testFindByOwnerName() { + // Given + final Person p1 = createPerson("p1"); + final Person p2 = createPerson("p2"); + + final Document d1 = createDocument("d1", p1); + final Document d2 = createDocument("d2", p2); + final Document d3 = createDocument("d3", p2); + + // When + List actual = DocumentAccessors.of(readOnlyDocumentRepository.findByOwnerName(p2.getName())); + List actualIds = getIdsFromViews(actual); + + // Then + assertEquals(2, actual.size()); + assertTrue(actualIds.contains(d2.getId())); + assertTrue(actualIds.contains(d3.getId())); + } + + @Test + public void testFindByAgeGreaterThanEqual() { + // Given + final Document d1 = createDocument("d1", null, 3L, null); + final Document d2 = createDocument("d2", null, 4L, null); + final Document d3 = createDocument("d3", null, 5L, null); + + // When + List actual = DocumentAccessors.of(readOnlyDocumentRepository.findByAgeGreaterThanEqual(4L)); + List actualIds = getIdsFromViews(actual); + + // Then + assertEquals(2, actual.size()); + assertTrue(actualIds.contains(d2.getId())); + assertTrue(actualIds.contains(d3.getId())); + } + + @Test + public void testFindSliceByAgeGreaterThanEqual() { + // Given + final Document d1 = createDocument("d1", null, 3L, null); + final Document d2 = createDocument("d2", null, 4L, null); + final Document d3 = createDocument("d3", null, 5L, null); + + // When + Slice actual = DocumentAccessors.of(readOnlyDocumentRepository.findSliceByAgeGreaterThanEqual(4L, new PageRequest(1, 1, "age", "id"))); + List actualIds = getIdsFromViews(actual); + + // Then + assertEquals(1, actual.getSize()); + assertFalse(actual.hasNext()); + assertTrue(actual.hasPrevious()); + assertTrue(actualIds.contains(d3.getId())); + } + + @Test + public void testFindFirstByOrderByNameAsc() { + // Given + final Document d3 = createDocument("d3"); + final Document d2 = createDocument("d2"); + final Document d1 = createDocument("d1"); + + // When + DocumentAccessor actual = DocumentAccessors.of(readOnlyDocumentRepository.findFirstByOrderByNameAsc()); + + // Then + assertEquals(d1.getId(), actual.getId()); + } + + @Test + public void testFindByAgeIn() { + // ignored with EclipseLink due to IN collection rendering bug + Assume.assumeFalse(isEclipseLink()); + // Given + final Document d3 = createDocument("d3"); + final Document d2 = createDocument("d2"); + final Document d1 = createDocument("d1"); + + // When + + List actual1 = DocumentAccessors.of(readOnlyDocumentRepository.findByNameIn(new HashSet(0))); + List actual2 = DocumentAccessors.of(readOnlyDocumentRepository.findByAgeIn(new Long[0])); + + // Then + assertEquals(0, actual1.size()); + assertEquals(0, actual2.size()); + } + + @Test + public void testFindOneBySpec() { + // Given + final Document d3 = createDocument("d3", null, 3L, null); + final Document d2 = createDocument("d2", null, 2L, null); + final Document d1 = createDocument("d1", null, 1L, null); + + // When + DocumentAccessor actual = DocumentAccessors.of(((ReadOnlyDocumentRepository) readOnlyDocumentRepository).findOne(new Specification() { + @Override + public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) { + return criteriaBuilder.equal(root.get("name"), "d2"); + } + })); + + // Then + assertTrue(actual.getId().equals(d2.getId())); + } + + @Test + public void testFindAllBySpec() { + // Given + final Document d3 = createDocument("d3", null, 3L, null); + final Document d2 = createDocument("d2", null, 2L, null); + final Document d1 = createDocument("d1", null, 1L, null); + + // When + List actual = DocumentAccessors.of(((ReadOnlyDocumentRepository) readOnlyDocumentRepository).findAll(new Specification() { + @Override + public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) { + return criteriaBuilder.ge(root.get("age"), 2L); + } + })); + List actualIds = getIdsFromViews(actual); + + // Then + assertEquals(2, actual.size()); + assertTrue(actualIds.contains(d2.getId())); + assertTrue(actualIds.contains(d3.getId())); + } + + @Test + public void testFindAllBySpecPageable() { + // Given + final Document d4 = createDocument("d4", null, 2L, null); + final Document d3 = createDocument("d3", null, 3L, null); + final Document d2 = createDocument("d2", null, 2L, null); + final Document d1 = createDocument("d1", null, 1L, null); + + // When + Page actual = DocumentAccessors.of(((ReadOnlyDocumentRepository) readOnlyDocumentRepository).findAll(new Specification() { + @Override + public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) { + return criteriaBuilder.gt(root.get("age"), 1L); + } + }, new PageRequest(1, 2, "name", "id"))); + List actualIds = getIdsFromViews(actual); + + // Then + assertEquals(1, actual.getNumberOfElements()); + assertTrue(actualIds.contains(d4.getId())); + } + + @Test + public void testFindAllBySpecSorted() { + // Given + final Document d3 = createDocument("d3", null, 3L, null); + final Document d2 = createDocument("d2", null, 2L, null); + final Document d1 = createDocument("d1", null, 1L, null); + + // When + List actual = DocumentAccessors.of(((ReadOnlyDocumentRepository) readOnlyDocumentRepository).findAll(new Specification() { + @Override + public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) { + return criteriaBuilder.ge(root.get("age"), 2L); + } + }, Sort.asc("name"))); + + // Then + assertEquals(2, actual.size()); + assertTrue(actual.get(0).getId().equals(d2.getId())); + assertTrue(actual.get(1).getId().equals(d3.getId())); + } + + @Test + public void testFindWithOptionalParameter() { + // Given + String name = "D1"; + String param = "Foo"; + createDocument(name); + + // When + List result = readOnlyDocumentRepository.findByName(name, param); + + // Then + assertEquals(1, result.size()); + String optionalParameter = result.get(0).getOptionalParameter(); + assertEquals(param, optionalParameter); + } + + @Test + public void testFindWithOptionalParameterAndPageable() { + // Given + String name = "D1"; + String param = "Foo"; + createDocument("D1"); + + // When + Page result = readOnlyDocumentRepository.findByNameOrderById(name, new PageRequest(0, 1), param); + + // Then + assertEquals(1, result.getSize()); + String optionalParameter = result.getContent().get(0).getOptionalParameter(); + assertEquals(param, optionalParameter); + } + + @Test + public void testFindAllBySpecWithOptionalParameter() { + // Given + final Document d3 = createDocument("d3", null, 3L, null); + final Document d2 = createDocument("d2", null, 2L, null); + final Document d1 = createDocument("d1", null, 1L, null); + + final String param = "Foo"; + + // When + List actual = readOnlyDocumentRepository.findAll(new Specification() { + + @Override + public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) { + return criteriaBuilder.ge(root.get("age"), 2L); + } + }, param); + + // Then + assertEquals(2, actual.size()); + assertEquals(actual.get(0).getOptionalParameter(), param); + } + + @Test + public void testEntityViewSettingProcessorParameter() { + // Given + String name = "D1"; + String param = "Foo"; + createDocument(name); + + // When + List actual = readOnlyDocumentRepository.findAll(new EntityViewSettingProcessor() { + + @Override + public EntityViewSetting acceptEntityViewSetting(EntityViewSetting setting) { + setting.addOptionalParameter("optionalParameter", param); + return setting; + } + }); + + // Then + assertEquals(1, actual.size()); + assertEquals(actual.get(0).getOptionalParameter(), param); + } + + @Test + public void testBlazeSpecificationParameter() { + // Given + String name = "D1"; + createDocument(name); + + // When + List actual = readOnlyDocumentRepository.findAll(new BlazeSpecification() { + @Override + public void applySpecification(String rootAlias, com.blazebit.persistence.CriteriaBuilder builder) { + builder.where("name").eqExpression("'D2'"); + } + }); + + // Then + assertEquals(0, actual.size()); + } + + @Test + public void testFindAllBySpecWithKeysetExtraction() { + // Given + final Document d3 = createDocument("d3", null, 3L, null); + final Document d2 = createDocument("d2", null, 2L, null); + final Document d1 = createDocument("d1", null, 1L, null); + + final String param = "Foo"; + + Pageable pageable = new KeysetPageRequest(null, Sort.asc("id"), 0, 3, true, true); + + // When + Page actual = readOnlyDocumentRepository.findAll(new Specification() { + + @Override + public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) { + return criteriaBuilder.conjunction(); + } + }, pageable); + KeysetAwarePage keysetAwarePage = (KeysetAwarePage) actual; + + // Then + assertEquals(3, keysetAwarePage.getKeysetPage().getKeysets().size()); + } + + @Test + public void testEntityViewAttributeSorting() { + // Given + String doc1 = "D1"; + String doc2 = "D2"; + String doc3 = "D3"; + Person person = createPerson("Foo"); + createDocument(doc1, person); + createDocument(doc2, person); + createDocument(doc3, createPerson("Bar")); + + String sortProperty = "ownerDocumentCount"; + + List list = readOnlyDocumentRepository.findAll(Sort.asc(sortProperty)); + + assertEquals(doc3, list.get(0).getName()); + + list = readOnlyDocumentRepository.findAll(Sort.desc(sortProperty)); + + assertEquals(doc3, list.get(2).getName()); + } + + @Test + public void testMixedEntityViewAndEntityAttributeSortingPartTree() { + // Given + String doc1 = "D1"; + String doc2 = "D2"; + String doc3 = "D2"; + Person person = createPerson("Foo"); + createDocument(doc1, "A", 0L, person); + createDocument(doc2, "B", 0L, person); + createDocument(doc3, createPerson("Bar")); + + String entityViewSortProperty = "ownerDocumentCount"; + String entitySortProperty = "description"; + + List list = readOnlyDocumentRepository.findAll( + Sort.of( + new org.springframework.data.domain.Sort.Order(org.springframework.data.domain.Sort.Direction.ASC, entityViewSortProperty), + new org.springframework.data.domain.Sort.Order(org.springframework.data.domain.Sort.Direction.DESC, entitySortProperty) + ), + "foo"); + + assertEquals(doc3, list.get(0).getName()); + assertEquals(doc2, list.get(1).getName()); + assertEquals(doc1, list.get(2).getName()); + + list = readOnlyDocumentRepository.findAll( + Sort.of( + new org.springframework.data.domain.Sort.Order(org.springframework.data.domain.Sort.Direction.ASC, entitySortProperty), + new org.springframework.data.domain.Sort.Order(org.springframework.data.domain.Sort.Direction.ASC, entityViewSortProperty) + ), + "foo"); + + assertEquals(doc1, list.get(0).getName()); + assertEquals(doc3, list.get(1).getName()); + assertEquals(doc2, list.get(2).getName()); + } + + @Test + public void testPageableSortOrder() { + // Given + String doc1 = "D1"; + String doc2 = "D2"; + String doc3 = "D2"; + String doc4 = "D2"; + Person person = createPerson("Foo"); + Document d1 = createDocument(doc1, "A", 0L, person); + Document d2 = createDocument(doc2, "B", 0L, person); + Document d3 = createDocument(doc3, "B", 0L, person); + Document d4 = createDocument(doc4, createPerson("Bar")); + + String entityViewSortProperty = "ownerDocumentCount"; + String entitySortProperty = "description"; + + // When + Page actual = DocumentAccessors.of(((ReadOnlyDocumentRepository) readOnlyDocumentRepository).findAllByOrderByNameAsc( + new PageRequest(0, 3, entityViewSortProperty, entitySortProperty), evs -> { + evs.addAttributeSorter("id", Sorters.ascending()); + return evs; + } + )); + List actualIds = getIdsFromViews(actual); + + // Then + assertEquals(3, actual.getNumberOfElements()); + assertEquals(actualIds.get(0), d1.getId()); + assertEquals(actualIds.get(1), d4.getId()); + assertEquals(actualIds.get(2), d2.getId() < d3.getId() ? d2.getId() : d3.getId()); + } + + @Test + public void testNonPageableSortOrder() { + // Given + String doc1 = "D1"; + String doc2 = "D2"; + String doc3 = "D2"; + String doc4 = "D2"; + Person person = createPerson("Foo"); + Document d1 = createDocument(doc1, "A", 0L, person); + Document d2 = createDocument(doc2, "B", 0L, person); + Document d3 = createDocument(doc3, "B", 0L, person); + Document d4 = createDocument(doc4, createPerson("Bar")); + + String entityViewSortProperty = "ownerDocumentCount"; + String entitySortProperty = "description"; + + // When + List actual = DocumentAccessors.of(((ReadOnlyDocumentRepository) readOnlyDocumentRepository).findAllByOrderByNameAsc( + Sort.asc(entityViewSortProperty, entitySortProperty),evs -> { + evs.addAttributeSorter("id", Sorters.ascending()); + return evs; + } + )); + List actualIds = getIdsFromViews(actual); + + // Then + assertEquals(4, actual.size()); + assertEquals(actualIds.get(0), d1.getId()); + assertEquals(actualIds.get(1), d4.getId()); + assertEquals(actualIds.get(2), d2.getId() < d3.getId() ? d2.getId() : d3.getId()); + assertEquals(actualIds.get(3), d2.getId() < d3.getId() ? d3.getId() : d2.getId()); + } + + @Test + public void testUnpaged() { + // Given + final Document d1 = createDocument("D1"); + final Document d2 = createDocument("D2"); + + // When + Page result = DocumentAccessors.of(readOnlyDocumentRepository.findAll( + new Specification() { + @Override + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) { + return null; + } + }, + UNPAGED + )); + + // Then + List actualIds = getIdsFromViews(result); + + // Then + assertEquals(2, actualIds.size()); + assertTrue(actualIds.contains(d1.getId())); + assertTrue(actualIds.contains(d2.getId())); + } + + // Test for #1817 + // No idea what's wrong with Datanucleus + @Test + @Category({ NoDatanucleus.class }) + public void testFindByEnum() { + // Given + final Document d1 = createDocument("D1", "test", 0, null); + + // When + int elementCount = readOnlyDocumentRepository.countDocumentsByStatus(MyEnum.ABC); + + // Then + assertEquals(1, elementCount); + } + + @Test + public void testSortByExpression() { + // Given + final Document d1 = createDocument("D1", "test", 0, null); + + // When + try { + readOnlyDocumentRepository.findAll(Sort.of(new org.springframework.data.domain.Sort.Order(null, "1"))); + Assert.fail("Should fail because '1' is not a valid property to sort by"); + } catch (RuntimeException ex) { + // Then + assertTrue( ex.getMessage().contains( "Sort order [1] is not resolvable to a path expression" ) ); + } + } + + private List getIdsFromViews(Iterable views) { + List ids = new ArrayList<>(); + for (DocumentAccessor view : views) { + ids.add(view.getId()); + } + return ids; + } + + private Document createDocument(String name) { + return createDocument(name, null); + } + + private Document createDocument(final String name, final Person owner) { + return createDocument(name, null, 0L, owner); + } + + private Document createDocument(final String name, final String description, final long age, final Person owner) { + return transactionalWorkService.doTxWork(new TxWork() { + @Override + public Document work(EntityManager em, EntityViewManager evm) { + Document d = new Document(name); + d.setDescription(description); + d.setAge(age); + em.persist(d); + if (owner != null) { + d.setOwner(em.getReference(Person.class, owner.getId())); + } + return d; + } + }); + } + + private Person createPerson(final String name) { + return transactionalWorkService.doTxWork(new TxWork() { + @Override + public Person work(EntityManager em, EntityViewManager evm) { + Person p = new Person(name); + em.persist(p); + return p; + } + }); + } + + private boolean isEntityRepository() { + return repositoryClass == ReadOnlyDocumentEntityRepository.class; + } + + private boolean isEclipseLink() { + return Arrays.asList(new SystemPropertyBasedActiveProfilesResolver().resolve( + ParameterizedReadOnlyDocumentRepositoryTest.class)).contains("eclipselink"); + } + + @Configuration + @ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = ".*TestConfig")) + @ImportResource("classpath:/com/blazebit/persistence/spring/data/testsuite/webmvc/application-config.xml") + @EnableEntityViews(basePackages = "com.blazebit.persistence.spring.data.testsuite.webmvc.view") + @EnableBlazeRepositories( + basePackages = "com.blazebit.persistence.spring.data.testsuite.webmvc.repository", + entityManagerFactoryRef = "myEmf" + ) + static class TestConfig { + } +} diff --git a/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/ReadOnlyDocumentRepositoryTest.java b/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/ReadOnlyDocumentRepositoryTest.java index 1db3f629d7..28552da99c 100644 --- a/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/ReadOnlyDocumentRepositoryTest.java +++ b/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/ReadOnlyDocumentRepositoryTest.java @@ -5,901 +5,91 @@ package com.blazebit.persistence.spring.data.testsuite.webmvc; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import com.blazebit.persistence.integration.view.spring.EnableEntityViews; -import com.blazebit.persistence.spring.data.repository.BlazeSpecification; -import com.blazebit.persistence.spring.data.repository.EntityViewSettingProcessor; -import com.blazebit.persistence.spring.data.repository.KeysetAwarePage; -import com.blazebit.persistence.spring.data.repository.KeysetPageRequest; import com.blazebit.persistence.spring.data.repository.config.EnableBlazeRepositories; -import com.blazebit.persistence.spring.data.testsuite.webmvc.accessor.DocumentAccessor; -import com.blazebit.persistence.spring.data.testsuite.webmvc.accessor.DocumentAccessors; -import com.blazebit.persistence.spring.data.testsuite.webmvc.config.SystemPropertyBasedActiveProfilesResolver; import com.blazebit.persistence.spring.data.testsuite.webmvc.entity.Document; -import com.blazebit.persistence.spring.data.testsuite.webmvc.entity.MyEnum; +import com.blazebit.persistence.spring.data.testsuite.webmvc.entity.Identifiable; import com.blazebit.persistence.spring.data.testsuite.webmvc.entity.Person; import com.blazebit.persistence.spring.data.testsuite.webmvc.repository.ReadOnlyDocumentEntityRepository; -import com.blazebit.persistence.spring.data.testsuite.webmvc.repository.ReadOnlyDocumentRepository; import com.blazebit.persistence.spring.data.testsuite.webmvc.repository.ReadOnlyDocumentViewRepository; import com.blazebit.persistence.spring.data.testsuite.webmvc.tx.TransactionalWorkService; import com.blazebit.persistence.spring.data.testsuite.webmvc.tx.TxWork; import com.blazebit.persistence.spring.data.testsuite.webmvc.view.DocumentView; -import com.blazebit.persistence.testsuite.base.jpa.category.NoDB2; -import com.blazebit.persistence.testsuite.base.jpa.category.NoDatanucleus; -import com.blazebit.persistence.testsuite.base.jpa.category.NoEclipselink; -import com.blazebit.persistence.testsuite.base.jpa.category.NoFirebird; -import com.blazebit.persistence.testsuite.base.jpa.category.NoHibernate42; -import com.blazebit.persistence.testsuite.base.jpa.category.NoMySQL; -import com.blazebit.persistence.testsuite.base.jpa.category.NoOracle; -import com.blazebit.persistence.testsuite.base.jpa.category.NoPostgreSQL; -import com.blazebit.persistence.testsuite.base.jpa.category.NoSQLite; import com.blazebit.persistence.view.EntityViewManager; -import com.blazebit.persistence.view.EntityViewSetting; -import com.blazebit.persistence.view.Sorters; - -import org.junit.Assert; -import org.junit.Assume; -import org.junit.Before; +import java.lang.reflect.Method; +import java.util.List; +import java.util.stream.Collectors; +import javax.persistence.EntityManager; import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.context.annotation.ImportResource; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.data.jpa.domain.Specification; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; -import javax.persistence.EntityManager; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - /** * @author Moritz Becker - * @since 1.2.0 + * @since 1.6.15 */ -@RunWith(Parameterized.class) @ContextConfiguration(classes = ReadOnlyDocumentRepositoryTest.TestConfig.class) @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) public class ReadOnlyDocumentRepositoryTest extends AbstractSpringTest { - @Parameterized.Parameters - public static Iterable createParameters() { - return Arrays.asList(ReadOnlyDocumentViewRepository.class, ReadOnlyDocumentEntityRepository.class); - } + private static final Pageable UNPAGED; - private final Class> repositoryClass; + static { + Pageable unpaged = null; + try { + Method unpagedMethod = Class.forName("org.springframework.data.domain.Pageable").getMethod("unpaged"); + unpaged = (Pageable) unpagedMethod.invoke(null); + } catch (Exception e) { + // ignore + } + UNPAGED = unpaged; + } @Autowired - private AutowireCapableBeanFactory autowireCapableBeanFactory; - + private ReadOnlyDocumentEntityRepository documentEntityRepository; + @Autowired + private ReadOnlyDocumentViewRepository documentViewRepository; @Autowired private TransactionalWorkService transactionalWorkService; - private ReadOnlyDocumentRepository readOnlyDocumentRepository; - - public ReadOnlyDocumentRepositoryTest(Class> repositoryClass) { - this.repositoryClass = repositoryClass; - } - - @Before - public void initRepository() { - readOnlyDocumentRepository = autowireCapableBeanFactory.getBean(repositoryClass); - } - - // NOTE: EclipseLink and DataNucleus seem to have a problem with the way Spring Data makes use of entity graphs, although it just uses the JPA APIs - // Hibernate 4.2 doesn't support the JPA 2.1 APIs that introduced entity graphs - @Test - @Category({ NoHibernate42.class, NoEclipselink.class, NoDatanucleus.class }) - public void testFindD1EntityGraph() { - // Given - final Document d1 = createDocument("D1"); - final Document d2 = createDocument("D2"); - - // When - Document d = readOnlyDocumentRepository.findD1EntityGraph(); - - // Then - assertEquals(d1.getId(), d.getId()); - } - - @Test - public void testFindD1NamedQuery() { - // Given - final Document d1 = createDocument("D1"); - final Document d2 = createDocument("D2"); - - // When - Document d = readOnlyDocumentRepository.findD1NamedQuery(); - - // Then - assertEquals(d1.getId(), d.getId()); - } - - @Test - // We don't want to deal with the different casing requirements for table names in the various DBs so we only run - // this test for H2. - // DataNucleus is not able to create entities from native query result sets. - @Category({NoDatanucleus.class, NoPostgreSQL.class, NoOracle.class, NoMySQL.class, NoSQLite.class, NoFirebird.class, NoDB2.class}) - public void testFindD1Native() { - // Given - final Document d1 = createDocument("D1"); - final Document d2 = createDocument("D2"); - - // When - Document d = readOnlyDocumentRepository.findD1Native(); - - // Then - assertEquals(d1.getId(), d.getId()); - } - - @Test - public void testFindD1Projection() { - // Given - final Document d1 = createDocument("D1"); - final Document d2 = createDocument("D2"); - - // When - Long id = readOnlyDocumentRepository.findD1Projection(); - - // Then - assertEquals(d1.getId(), id); - } - - @Test - public void testFindD1NamedQueryProjection() { - // Given - final Document d1 = createDocument("D1"); - final Document d2 = createDocument("D2"); - - // When - Long id = readOnlyDocumentRepository.findD1NamedQueryProjection(); - - // Then - assertEquals(d1.getId(), id); - } - - @Test - // We don't want to deal with the different casing requirements for table names in the various DBs so we only run - // this test for H2. - @Category({NoPostgreSQL.class, NoOracle.class, NoMySQL.class, NoSQLite.class, NoFirebird.class, NoDB2.class}) - public void testFindD1NativeProjection() { - // Given - final Document d1 = createDocument("D1"); - final Document d2 = createDocument("D2"); - - // When - Long id = readOnlyDocumentRepository.findD1NativeProjection(); - - // Then - assertEquals(d1.getId(), id); - } - - @Test - public void testFindOne() { - // Given - final Document d1 = createDocument("D1"); - final Document d2 = createDocument("D2"); - - // When - DocumentAccessor result1 = DocumentAccessors.of(readOnlyDocumentRepository.findOne(d1.getId())); - DocumentAccessor result2 = DocumentAccessors.of(readOnlyDocumentRepository.findOne(d2.getId())); - - // Then - assertEquals(d1.getId(), result1.getId()); - assertNotNull(result1); - - assertEquals(d2.getId(), result2.getId()); - assertNotNull(result2); - } - - @Test - public void testExists(){ - // Given - final Document d1 = createDocument("D1"); - - // When - boolean existsP1 = readOnlyDocumentRepository.exists(d1.getId()); - - // Then - assertTrue(existsP1); - } - - @Test - public void testFindAll() { - // Given - final Person p1 = createPerson("P1"); - final Document d1 = createDocument("D1", p1); - final Document d2 = createDocument("D2", p1); - - // When - Iterable actual = DocumentAccessors.of(readOnlyDocumentRepository.findAll()); - List actualIds = getIdsFromViews(actual); - - // Then - assertEquals(2, actualIds.size()); - assertTrue(actualIds.contains(d1.getId())); - assertTrue(actualIds.contains(d2.getId())); - } - @Test - public void testFindAllByIds() { - // ignored with EclipseLink due to IN collection rendering bug - Assume.assumeFalse(isEntityRepository() && isEclipseLink()); + public void dynamicProjectionWithUnpagedPagination() { // Given - final Document d1 = createDocument("D1"); - final Document d2 = createDocument("D2"); + Document d1 = createDocument("A"); + Document d2 = createDocument("A"); + createDocument("B"); // When - Iterable actual = DocumentAccessors.of(readOnlyDocumentRepository.findAll(Arrays.asList(d1.getId(), d2.getId()))); - List actualIds = getIdsFromViews(actual); + Page entityPage = documentEntityRepository.findByName("A", Document.class, UNPAGED); + Page viewPage = documentViewRepository.findByName("A", DocumentView.class, UNPAGED); // Then - assertEquals(2, actualIds.size()); - assertTrue(actualIds.contains(d1.getId())); - assertTrue(actualIds.contains(d2.getId())); - } - - @Test - public void testCount() { - // Given - final Document d1 = createDocument("D1"); - final Document d2 = createDocument("D2"); - - // When - long count = readOnlyDocumentRepository.count(); - - // Then - assertEquals(2, count); - } - - @Test - public void testFindByName() { - // Given - final Document d1 = createDocument("D1"); - - // When - List result = DocumentAccessors.of(readOnlyDocumentRepository.findByName(d1.getName())); - - // Then - assertEquals(1, result.size()); - assertEquals(d1.getId(), result.get(0).getId()); - } - - @Test - public void testFindByDescription() { - // Given - final Document d1 = createDocument("D1", "test", 0, null); - - // When - List elements = readOnlyDocumentRepository.findByDescription(d1.getDescription()); - - // Then - assertEquals(1, elements.size()); - if (repositoryClass == ReadOnlyDocumentViewRepository.class) { - assertTrue(elements.get(0) instanceof Document); - } else { - assertTrue(elements.get(0) instanceof DocumentView); - } - List result = DocumentAccessors.of(elements); - assertEquals(d1.getId(), result.get(0).getId()); - } - - @Test - public void testFindByNameAndAgeOrDescription() { - // Given - final String name = "D1"; - final Document d1 = createDocument(name, "desc1", 12, null); - final Document d2 = createDocument(name, "desc2", 13, null); - final Document d3 = createDocument(name, "desc3", 14, null); - - // When - List actual = DocumentAccessors.of(readOnlyDocumentRepository.findByNameAndAgeOrDescription(name, 12, "desc2")); - List actualIds = getIdsFromViews(actual); - - // Then - assertEquals(2, actual.size()); - assertTrue(actualIds.contains(d1.getId())); - assertTrue(actualIds.contains(d2.getId())); - } - - @Test - public void testFindByNameIn() { - // ignored with EclipseLink due to IN collection rendering bug - Assume.assumeFalse(isEntityRepository() && isEclipseLink()); - // Given - final Document d1 = createDocument("d1"); - final Document d2 = createDocument("d2"); - final Document d3 = createDocument("d3"); - - // When - List actual = DocumentAccessors.of(readOnlyDocumentRepository.findByNameIn(d2.getName(), d3.getName())); - List actualIds = getIdsFromViews(actual); - - // Then - assertEquals(2, actual.size()); - assertTrue(actualIds.contains(d2.getId())); - assertTrue(actualIds.contains(d3.getId())); - } - - @Test - public void testFindByNameInPaginated() { - // ignored with EclipseLink due to IN collection rendering bug - Assume.assumeFalse(isEntityRepository() && isEclipseLink()); - // Given - final Document d1 = createDocument("d1"); - final Document d2 = createDocument("d2"); - final Document d3 = createDocument("d3"); - - // When - Page actual = DocumentAccessors.of(readOnlyDocumentRepository.findByNameInOrderById(new PageRequest(0, 1), d2.getName(), d3.getName())); - List actualIds = getIdsFromViews(actual); - - // Then - assertEquals(2, actual.getTotalPages()); - assertEquals(0, actual.getNumber()); - assertEquals(1, actual.getNumberOfElements()); - assertEquals(1, actual.getSize()); - assertTrue(actualIds.contains(d2.getId())); - - actual = DocumentAccessors.of(readOnlyDocumentRepository.findByNameInOrderById(actual.nextPageable(), d2.getName(), d3.getName())); - actualIds = getIdsFromViews(actual); - assertEquals(2, actual.getTotalPages()); - assertEquals(1, actual.getNumber()); - assertEquals(1, actual.getNumberOfElements()); - assertEquals(1, actual.getSize()); - assertTrue(actualIds.contains(d3.getId())); - } - - @Test - public void testFindByNameInKeysetPaginated() { - // ignored with EclipseLink due to IN collection rendering bug - Assume.assumeFalse(isEntityRepository() && isEclipseLink()); - // Given - final Document d1 = createDocument("d1"); - final Document d2 = createDocument("d2"); - final Document d3 = createDocument("d3"); - - // When - KeysetAwarePage actual = DocumentAccessors.of(readOnlyDocumentRepository.findByNameIn(new KeysetPageRequest(null, Sort.asc("id"), 0, 1), d2.getName(), d3.getName())); - List actualIds = getIdsFromViews(actual); - - // Then - assertEquals(2, actual.getTotalPages()); - assertEquals(0, actual.getNumber()); - assertEquals(1, actual.getNumberOfElements()); - assertEquals(1, actual.getSize()); - assertTrue(actualIds.contains(d2.getId())); - - actual = DocumentAccessors.of(readOnlyDocumentRepository.findByNameIn(actual.nextPageable(), d2.getName(), d3.getName())); - actualIds = getIdsFromViews(actual); - assertEquals(2, actual.getTotalPages()); - assertEquals(1, actual.getNumber()); - assertEquals(1, actual.getNumberOfElements()); - assertEquals(1, actual.getSize()); - assertTrue(actualIds.contains(d3.getId())); - } - - @Test - public void testFindByNameLikeOrderByAgeAsc() { - // Given - final Document d1 = createDocument("d1", null, 2l, null); - final Document d2 = createDocument("d2", null, 1l, null); - - // When - List actual = DocumentAccessors.of(readOnlyDocumentRepository.findByNameLikeOrderByAgeAsc("d%")); - - // Then - assertEquals(2, actual.size()); - assertEquals(d2.getId(), actual.get(0).getId()); - assertEquals(d1.getId(), actual.get(1).getId()); - } - - @Test - public void testFindByOwnerName() { - // Given - final Person p1 = createPerson("p1"); - final Person p2 = createPerson("p2"); - - final Document d1 = createDocument("d1", p1); - final Document d2 = createDocument("d2", p2); - final Document d3 = createDocument("d3", p2); - - // When - List actual = DocumentAccessors.of(readOnlyDocumentRepository.findByOwnerName(p2.getName())); - List actualIds = getIdsFromViews(actual); - - // Then - assertEquals(2, actual.size()); - assertTrue(actualIds.contains(d2.getId())); - assertTrue(actualIds.contains(d3.getId())); - } - - @Test - public void testFindByAgeGreaterThanEqual() { - // Given - final Document d1 = createDocument("d1", null, 3L, null); - final Document d2 = createDocument("d2", null, 4L, null); - final Document d3 = createDocument("d3", null, 5L, null); - - // When - List actual = DocumentAccessors.of(readOnlyDocumentRepository.findByAgeGreaterThanEqual(4L)); - List actualIds = getIdsFromViews(actual); - - // Then - assertEquals(2, actual.size()); - assertTrue(actualIds.contains(d2.getId())); - assertTrue(actualIds.contains(d3.getId())); - } - - @Test - public void testFindSliceByAgeGreaterThanEqual() { - // Given - final Document d1 = createDocument("d1", null, 3L, null); - final Document d2 = createDocument("d2", null, 4L, null); - final Document d3 = createDocument("d3", null, 5L, null); - - // When - Slice actual = DocumentAccessors.of(readOnlyDocumentRepository.findSliceByAgeGreaterThanEqual(4L, new PageRequest(1, 1, "age", "id"))); - List actualIds = getIdsFromViews(actual); - - // Then - assertEquals(1, actual.getSize()); - assertFalse(actual.hasNext()); - assertTrue(actual.hasPrevious()); - assertTrue(actualIds.contains(d3.getId())); - } - - @Test - public void testFindFirstByOrderByNameAsc() { - // Given - final Document d3 = createDocument("d3"); - final Document d2 = createDocument("d2"); - final Document d1 = createDocument("d1"); - - // When - DocumentAccessor actual = DocumentAccessors.of(readOnlyDocumentRepository.findFirstByOrderByNameAsc()); - - // Then - assertEquals(d1.getId(), actual.getId()); - } - - @Test - public void testFindByAgeIn() { - // ignored with EclipseLink due to IN collection rendering bug - Assume.assumeFalse(isEclipseLink()); - // Given - final Document d3 = createDocument("d3"); - final Document d2 = createDocument("d2"); - final Document d1 = createDocument("d1"); - - // When - - List actual1 = DocumentAccessors.of(readOnlyDocumentRepository.findByNameIn(new HashSet(0))); - List actual2 = DocumentAccessors.of(readOnlyDocumentRepository.findByAgeIn(new Long[0])); - - // Then - assertEquals(0, actual1.size()); - assertEquals(0, actual2.size()); - } - - @Test - public void testFindOneBySpec() { - // Given - final Document d3 = createDocument("d3", null, 3L, null); - final Document d2 = createDocument("d2", null, 2L, null); - final Document d1 = createDocument("d1", null, 1L, null); - - // When - DocumentAccessor actual = DocumentAccessors.of(((ReadOnlyDocumentRepository) readOnlyDocumentRepository).findOne(new Specification() { - @Override - public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) { - return criteriaBuilder.equal(root.get("name"), "d2"); - } - })); - - // Then - assertTrue(actual.getId().equals(d2.getId())); - } - - @Test - public void testFindAllBySpec() { - // Given - final Document d3 = createDocument("d3", null, 3L, null); - final Document d2 = createDocument("d2", null, 2L, null); - final Document d1 = createDocument("d1", null, 1L, null); - - // When - List actual = DocumentAccessors.of(((ReadOnlyDocumentRepository) readOnlyDocumentRepository).findAll(new Specification() { - @Override - public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) { - return criteriaBuilder.ge(root.get("age"), 2L); - } - })); - List actualIds = getIdsFromViews(actual); - - // Then - assertEquals(2, actual.size()); - assertTrue(actualIds.contains(d2.getId())); - assertTrue(actualIds.contains(d3.getId())); - } - - @Test - public void testFindAllBySpecPageable() { - // Given - final Document d4 = createDocument("d4", null, 2L, null); - final Document d3 = createDocument("d3", null, 3L, null); - final Document d2 = createDocument("d2", null, 2L, null); - final Document d1 = createDocument("d1", null, 1L, null); - - // When - Page actual = DocumentAccessors.of(((ReadOnlyDocumentRepository) readOnlyDocumentRepository).findAll(new Specification() { - @Override - public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) { - return criteriaBuilder.gt(root.get("age"), 1L); - } - }, new PageRequest(1, 2, "name", "id"))); - List actualIds = getIdsFromViews(actual); - - // Then - assertEquals(1, actual.getNumberOfElements()); - assertTrue(actualIds.contains(d4.getId())); - } - - @Test - public void testFindAllBySpecSorted() { - // Given - final Document d3 = createDocument("d3", null, 3L, null); - final Document d2 = createDocument("d2", null, 2L, null); - final Document d1 = createDocument("d1", null, 1L, null); - - // When - List actual = DocumentAccessors.of(((ReadOnlyDocumentRepository) readOnlyDocumentRepository).findAll(new Specification() { - @Override - public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) { - return criteriaBuilder.ge(root.get("age"), 2L); - } - }, Sort.asc("name"))); - - // Then - assertEquals(2, actual.size()); - assertTrue(actual.get(0).getId().equals(d2.getId())); - assertTrue(actual.get(1).getId().equals(d3.getId())); - } - - @Test - public void testFindWithOptionalParameter() { - // Given - String name = "D1"; - String param = "Foo"; - createDocument(name); - - // When - List result = readOnlyDocumentRepository.findByName(name, param); - - // Then - assertEquals(1, result.size()); - String optionalParameter = result.get(0).getOptionalParameter(); - assertEquals(param, optionalParameter); - } - - @Test - public void testFindWithOptionalParameterAndPageable() { - // Given - String name = "D1"; - String param = "Foo"; - createDocument("D1"); - - // When - Page result = readOnlyDocumentRepository.findByNameOrderById(name, new PageRequest(0, 1), param); - - // Then - assertEquals(1, result.getSize()); - String optionalParameter = result.getContent().get(0).getOptionalParameter(); - assertEquals(param, optionalParameter); - } - - @Test - public void testFindAllBySpecWithOptionalParameter() { - // Given - final Document d3 = createDocument("d3", null, 3L, null); - final Document d2 = createDocument("d2", null, 2L, null); - final Document d1 = createDocument("d1", null, 1L, null); - - final String param = "Foo"; - - // When - List actual = readOnlyDocumentRepository.findAll(new Specification() { - - @Override - public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) { - return criteriaBuilder.ge(root.get("age"), 2L); - } - }, param); - - // Then - assertEquals(2, actual.size()); - assertEquals(actual.get(0).getOptionalParameter(), param); - } - - @Test - public void testEntityViewSettingProcessorParameter() { - // Given - String name = "D1"; - String param = "Foo"; - createDocument(name); - - // When - List actual = readOnlyDocumentRepository.findAll(new EntityViewSettingProcessor() { - - @Override - public EntityViewSetting acceptEntityViewSetting(EntityViewSetting setting) { - setting.addOptionalParameter("optionalParameter", param); - return setting; - } - }); - - // Then - assertEquals(1, actual.size()); - assertEquals(actual.get(0).getOptionalParameter(), param); - } - - @Test - public void testBlazeSpecificationParameter() { - // Given - String name = "D1"; - createDocument(name); - - // When - List actual = readOnlyDocumentRepository.findAll(new BlazeSpecification() { - @Override - public void applySpecification(String rootAlias, com.blazebit.persistence.CriteriaBuilder builder) { - builder.where("name").eqExpression("'D2'"); - } - }); - - // Then - assertEquals(0, actual.size()); - } - - @Test - public void testFindAllBySpecWithKeysetExtraction() { - // Given - final Document d3 = createDocument("d3", null, 3L, null); - final Document d2 = createDocument("d2", null, 2L, null); - final Document d1 = createDocument("d1", null, 1L, null); - - final String param = "Foo"; - - Pageable pageable = new KeysetPageRequest(null, Sort.asc("id"), 0, 3, true, true); - - // When - Page actual = readOnlyDocumentRepository.findAll(new Specification() { - - @Override - public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) { - return criteriaBuilder.conjunction(); - } - }, pageable); - KeysetAwarePage keysetAwarePage = (KeysetAwarePage) actual; - - // Then - assertEquals(3, keysetAwarePage.getKeysetPage().getKeysets().size()); - } - - @Test - public void testEntityViewAttributeSorting() { - // Given - String doc1 = "D1"; - String doc2 = "D2"; - String doc3 = "D3"; - Person person = createPerson("Foo"); - createDocument(doc1, person); - createDocument(doc2, person); - createDocument(doc3, createPerson("Bar")); - - String sortProperty = "ownerDocumentCount"; - - List list = readOnlyDocumentRepository.findAll(Sort.asc(sortProperty)); - - assertEquals(doc3, list.get(0).getName()); - - list = readOnlyDocumentRepository.findAll(Sort.desc(sortProperty)); - - assertEquals(doc3, list.get(2).getName()); - } - - @Test - public void testMixedEntityViewAndEntityAttributeSortingPartTree() { - // Given - String doc1 = "D1"; - String doc2 = "D2"; - String doc3 = "D2"; - Person person = createPerson("Foo"); - createDocument(doc1, "A", 0L, person); - createDocument(doc2, "B", 0L, person); - createDocument(doc3, createPerson("Bar")); - - String entityViewSortProperty = "ownerDocumentCount"; - String entitySortProperty = "description"; - - List list = readOnlyDocumentRepository.findAll( - Sort.of( - new org.springframework.data.domain.Sort.Order(org.springframework.data.domain.Sort.Direction.ASC, entityViewSortProperty), - new org.springframework.data.domain.Sort.Order(org.springframework.data.domain.Sort.Direction.DESC, entitySortProperty) - ), - "foo"); - - assertEquals(doc3, list.get(0).getName()); - assertEquals(doc2, list.get(1).getName()); - assertEquals(doc1, list.get(2).getName()); - - list = readOnlyDocumentRepository.findAll( - Sort.of( - new org.springframework.data.domain.Sort.Order(org.springframework.data.domain.Sort.Direction.ASC, entitySortProperty), - new org.springframework.data.domain.Sort.Order(org.springframework.data.domain.Sort.Direction.ASC, entityViewSortProperty) - ), - "foo"); - - assertEquals(doc1, list.get(0).getName()); - assertEquals(doc3, list.get(1).getName()); - assertEquals(doc2, list.get(2).getName()); - } - - @Test - public void testPageableSortOrder() { - // Given - String doc1 = "D1"; - String doc2 = "D2"; - String doc3 = "D2"; - String doc4 = "D2"; - Person person = createPerson("Foo"); - Document d1 = createDocument(doc1, "A", 0L, person); - Document d2 = createDocument(doc2, "B", 0L, person); - Document d3 = createDocument(doc3, "B", 0L, person); - Document d4 = createDocument(doc4, createPerson("Bar")); - - String entityViewSortProperty = "ownerDocumentCount"; - String entitySortProperty = "description"; - - // When - Page actual = DocumentAccessors.of(((ReadOnlyDocumentRepository) readOnlyDocumentRepository).findAllByOrderByNameAsc( - new PageRequest(0, 3, entityViewSortProperty, entitySortProperty), evs -> { - evs.addAttributeSorter("id", Sorters.ascending()); - return evs; - } - )); - List actualIds = getIdsFromViews(actual); - - // Then - assertEquals(3, actual.getNumberOfElements()); - assertEquals(actualIds.get(0), d1.getId()); - assertEquals(actualIds.get(1), d4.getId()); - assertEquals(actualIds.get(2), d2.getId() < d3.getId() ? d2.getId() : d3.getId()); - } - - @Test - public void testNonPageableSortOrder() { - // Given - String doc1 = "D1"; - String doc2 = "D2"; - String doc3 = "D2"; - String doc4 = "D2"; - Person person = createPerson("Foo"); - Document d1 = createDocument(doc1, "A", 0L, person); - Document d2 = createDocument(doc2, "B", 0L, person); - Document d3 = createDocument(doc3, "B", 0L, person); - Document d4 = createDocument(doc4, createPerson("Bar")); - - String entityViewSortProperty = "ownerDocumentCount"; - String entitySortProperty = "description"; - - // When - List actual = DocumentAccessors.of(((ReadOnlyDocumentRepository) readOnlyDocumentRepository).findAllByOrderByNameAsc( - Sort.asc(entityViewSortProperty, entitySortProperty),evs -> { - evs.addAttributeSorter("id", Sorters.ascending()); - return evs; - } - )); - List actualIds = getIdsFromViews(actual); - - // Then - assertEquals(4, actual.size()); - assertEquals(actualIds.get(0), d1.getId()); - assertEquals(actualIds.get(1), d4.getId()); - assertEquals(actualIds.get(2), d2.getId() < d3.getId() ? d2.getId() : d3.getId()); - assertEquals(actualIds.get(3), d2.getId() < d3.getId() ? d3.getId() : d2.getId()); - } - - @Test - public void testUnpaged() { - // Given - final Document d1 = createDocument("D1"); - final Document d2 = createDocument("D2"); - - // When - Page result = DocumentAccessors.of(readOnlyDocumentRepository.findAll( - new Specification() { - @Override - public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) { - return null; - } - }, - unpaged() - )); - - // Then - List actualIds = getIdsFromViews(result); - - // Then - assertEquals(2, actualIds.size()); - assertTrue(actualIds.contains(d1.getId())); - assertTrue(actualIds.contains(d2.getId())); - } - - // Test for #1817 - // No idea what's wrong with Datanucleus - @Test - @Category({ NoDatanucleus.class }) - public void testFindByEnum() { - // Given - final Document d1 = createDocument("D1", "test", 0, null); - - // When - int elementCount = readOnlyDocumentRepository.countDocumentsByStatus(MyEnum.ABC); - - // Then - assertEquals(1, elementCount); - } - - @Test - public void testSortByExpression() { - // Given - final Document d1 = createDocument("D1", "test", 0, null); - - // When - try { - readOnlyDocumentRepository.findAll(Sort.of(new org.springframework.data.domain.Sort.Order(null, "1"))); - Assert.fail("Should fail because '1' is not a valid property to sort by"); - } catch (RuntimeException ex) { - // Then - assertTrue( ex.getMessage().contains( "Sort order [1] is not resolvable to a path expression" ) ); - } - } - - private Pageable unpaged() { - try { - Method unpaged = Class.forName("org.springframework.data.domain.Pageable").getMethod("unpaged"); - return (Pageable) unpaged.invoke(null); - } catch (Exception e) { - return null; - } - } - - private List getIdsFromViews(Iterable views) { - List ids = new ArrayList<>(); - for (DocumentAccessor view : views) { - ids.add(view.getId()); - } - return ids; + assertEquals(entityPage.getTotalElements(), viewPage.getTotalElements()); + assertEquals(entityPage.getTotalPages(), viewPage.getTotalPages()); + assertEquals(entityPage.getNumber(), viewPage.getNumber()); + assertEquals(entityPage.getSize(), viewPage.getSize()); + assertEquals(entityPage.getNumberOfElements(), viewPage.getNumberOfElements()); + assertEquals(entityPage.hasNext(), viewPage.hasNext()); + assertEquals(entityPage.hasPrevious(), viewPage.hasPrevious()); + assertEquals(entityPage.hasContent(), viewPage.hasContent()); + assertEquals(entityPage.isFirst(), viewPage.isFirst()); + assertEquals(entityPage.isLast(), viewPage.isLast()); + assertEquals(entityPage.getContent().size(), viewPage.getContent().size()); + List entityResultIds = entityPage.getContent().stream().map(Identifiable::getId).collect(Collectors.toList()); + assertTrue(entityResultIds.contains(d1.getId())); + assertTrue(entityResultIds.contains(d2.getId())); + List viewResultIds = viewPage.getContent().stream().map(Identifiable::getId).collect(Collectors.toList()); + assertEquals(entityResultIds, viewResultIds); } private Document createDocument(String name) { @@ -926,25 +116,6 @@ public Document work(EntityManager em, EntityViewManager evm) { }); } - private Person createPerson(final String name) { - return transactionalWorkService.doTxWork(new TxWork() { - @Override - public Person work(EntityManager em, EntityViewManager evm) { - Person p = new Person(name); - em.persist(p); - return p; - } - }); - } - - private boolean isEntityRepository() { - return repositoryClass == ReadOnlyDocumentEntityRepository.class; - } - - private boolean isEclipseLink() { - return Arrays.asList(new SystemPropertyBasedActiveProfilesResolver().resolve(ReadOnlyDocumentRepositoryTest.class)).contains("eclipselink"); - } - @Configuration @ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = ".*TestConfig")) @ImportResource("classpath:/com/blazebit/persistence/spring/data/testsuite/webmvc/application-config.xml") diff --git a/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/repository/ReadOnlyDocumentRepository.java b/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/repository/ReadOnlyDocumentRepository.java index 6708c20da7..cee35f783f 100644 --- a/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/repository/ReadOnlyDocumentRepository.java +++ b/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/repository/ReadOnlyDocumentRepository.java @@ -99,4 +99,6 @@ public interface ReadOnlyDocumentRepository extends EntityViewRepository findAllByOrderByNameAsc(Sort sort, EntityViewSettingProcessor processor); int countDocumentsByStatus(MyEnum status); + + Page findByName(String name, Class type, Pageable pageable); } diff --git a/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/view/DocumentUpdateView.java b/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/view/DocumentUpdateView.java index 96733f5b3e..6639e37f8a 100644 --- a/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/view/DocumentUpdateView.java +++ b/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/view/DocumentUpdateView.java @@ -6,6 +6,7 @@ package com.blazebit.persistence.spring.data.testsuite.webmvc.view; import com.blazebit.persistence.spring.data.testsuite.webmvc.entity.Document; +import com.blazebit.persistence.spring.data.testsuite.webmvc.entity.Identifiable; import com.blazebit.persistence.view.EntityView; import com.blazebit.persistence.view.IdMapping; import com.blazebit.persistence.view.UpdatableEntityView; @@ -16,9 +17,10 @@ */ @UpdatableEntityView @EntityView(Document.class) -public interface DocumentUpdateView { +public interface DocumentUpdateView extends Identifiable { @IdMapping + @Override Long getId(); String getName(); diff --git a/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/view/DocumentView.java b/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/view/DocumentView.java index 4c2dbabf44..28ee90d6ab 100644 --- a/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/view/DocumentView.java +++ b/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/view/DocumentView.java @@ -6,6 +6,7 @@ package com.blazebit.persistence.spring.data.testsuite.webmvc.view; import com.blazebit.persistence.spring.data.testsuite.webmvc.entity.Document; +import com.blazebit.persistence.spring.data.testsuite.webmvc.entity.Identifiable; import com.blazebit.persistence.view.EntityView; import com.blazebit.persistence.view.IdMapping; import com.blazebit.persistence.view.Mapping; @@ -18,9 +19,10 @@ * @since 1.5.0 */ @EntityView(Document.class) -public interface DocumentView { +public interface DocumentView extends Identifiable { @IdMapping + @Override Long getId(); String getName(); diff --git a/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/view/PersonUpdateView.java b/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/view/PersonUpdateView.java index 86b9367cb1..f0a39f68d4 100644 --- a/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/view/PersonUpdateView.java +++ b/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/view/PersonUpdateView.java @@ -5,6 +5,7 @@ package com.blazebit.persistence.spring.data.testsuite.webmvc.view; +import com.blazebit.persistence.spring.data.testsuite.webmvc.entity.Identifiable; import com.blazebit.persistence.spring.data.testsuite.webmvc.entity.Person; import com.blazebit.persistence.view.EntityView; import com.blazebit.persistence.view.IdMapping; @@ -18,9 +19,10 @@ */ @UpdatableEntityView @EntityView(Person.class) -public interface PersonUpdateView { +public interface PersonUpdateView extends Identifiable { @IdMapping + @Override UUID getId(); String getName(); diff --git a/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/view/PersonView.java b/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/view/PersonView.java index e17ea69802..57cc8bce1c 100644 --- a/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/view/PersonView.java +++ b/integration/spring-data/testsuite/webmvc/src/test/java/com/blazebit/persistence/spring/data/testsuite/webmvc/view/PersonView.java @@ -5,6 +5,7 @@ package com.blazebit.persistence.spring.data.testsuite.webmvc.view; +import com.blazebit.persistence.spring.data.testsuite.webmvc.entity.Identifiable; import com.blazebit.persistence.spring.data.testsuite.webmvc.entity.Person; import com.blazebit.persistence.view.EntityView; import com.blazebit.persistence.view.IdMapping; @@ -16,9 +17,10 @@ * @since 1.5.0 */ @EntityView(Person.class) -public interface PersonView { +public interface PersonView extends Identifiable { @IdMapping + @Override UUID getId(); String getName();