From 16790dc4a00efb8ee63aa76cc7f0b6c3c6484c65 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 25 Jul 2017 13:59:53 +0200 Subject: [PATCH] DATACASS-479 - Return domain type if projection type is an interface. We now return the domain type via CassandraQueryMethod.getEntityInformation() for query derivation. Previously, interface types were returned and they were used as input type for query derivation. Query methods referencing domain type properties that do not exist on the projection type caused PropertyReferenceException. --- .../query/CassandraQueryMethod.java | 15 +++++------ .../query/CassandraQueryMethodUnitTests.java | 17 ++++++++++++ .../PartTreeCassandraQueryUnitTests.java | 26 +++++++++++++------ 3 files changed, 41 insertions(+), 17 deletions(-) diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryMethod.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryMethod.java index 6892c220b..b04454030 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryMethod.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryMethod.java @@ -105,18 +105,15 @@ public class CassandraQueryMethod extends QueryMethod { mappingContext.getRequiredPersistentEntity(domainClass)); } else { - CassandraPersistentEntity entity = mappingContext.getPersistentEntity(returnedObjectType); + + CassandraPersistentEntity returnedEntity = mappingContext.getPersistentEntity(returnedObjectType); CassandraPersistentEntity managedEntity = mappingContext.getRequiredPersistentEntity(domainClass); - CassandraPersistentEntity returnedEntity = - entity != null && entity.getType().isInterface() ? entity : managedEntity; + returnedEntity = returnedEntity == null || returnedEntity.getType().isInterface() ? managedEntity + : returnedEntity; - // TODO collectionEntity? - CassandraPersistentEntity collectionEntity = - domainClass.isAssignableFrom(returnedObjectType) ? returnedEntity : managedEntity; - - this.entityMetadata = - new SimpleCassandraEntityMetadata<>((Class) returnedEntity.getType(), collectionEntity); + this.entityMetadata = new SimpleCassandraEntityMetadata<>((Class) returnedEntity.getType(), + managedEntity); } } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/CassandraQueryMethodUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/CassandraQueryMethodUnitTests.java index 14e6de2bb..2e09e1fa8 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/CassandraQueryMethodUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/CassandraQueryMethodUnitTests.java @@ -70,6 +70,14 @@ public class CassandraQueryMethodUnitTests { assertThat(queryMethod.isCollectionQuery()).isTrue(); } + @Test // DATACASS-479 + public void considersManagedEntityAsEntityInformation() throws Exception { + + CassandraQueryMethod queryMethod = queryMethod(SampleRepository.class, "findAllBy"); + + assertThat(queryMethod.getEntityInformation().getJavaType()).isEqualTo(User.class); + } + private CassandraQueryMethod queryMethod(Class repository, String name, Class... parameters) throws Exception { Method method = repository.getMethod(name, parameters); @@ -82,5 +90,14 @@ public class CassandraQueryMethodUnitTests { List method(); + UserProjection findAllBy(); + + } + + interface UserProjection { + + String getFirstname(); + + String getLastname(); } } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/PartTreeCassandraQueryUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/PartTreeCassandraQueryUnitTests.java index f2722b2a8..5811df0e2 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/PartTreeCassandraQueryUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/PartTreeCassandraQueryUnitTests.java @@ -15,8 +15,8 @@ */ package org.springframework.data.cassandra.repository.query; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.when; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; import java.lang.reflect.Method; import java.util.Arrays; @@ -30,7 +30,6 @@ import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; - import org.springframework.data.cassandra.core.CassandraOperations; import org.springframework.data.cassandra.core.convert.CassandraConverter; import org.springframework.data.cassandra.core.convert.MappingCassandraConverter; @@ -85,6 +84,7 @@ public class PartTreeCassandraQueryUnitTests { @Test // DATACASS-7 public void shouldDeriveSimpleQuery() { + String query = deriveQueryFromMethod("findByLastname", "foo"); assertThat(query).isEqualTo("SELECT * FROM person WHERE lastname='foo';"); @@ -92,6 +92,7 @@ public class PartTreeCassandraQueryUnitTests { @Test // DATACASS-7 public void shouldDeriveSimpleQueryWithoutNames() { + String query = deriveQueryFromMethod("findPersonBy"); assertThat(query).isEqualTo("SELECT * FROM person;"); @@ -99,6 +100,7 @@ public class PartTreeCassandraQueryUnitTests { @Test // DATACASS-7 public void shouldDeriveAndQuery() { + String query = deriveQueryFromMethod("findByFirstnameAndLastname", "foo", "bar"); assertThat(query).isEqualTo("SELECT * FROM person WHERE firstname='foo' AND lastname='bar';"); @@ -106,11 +108,20 @@ public class PartTreeCassandraQueryUnitTests { @Test // DATACASS-7 public void usesDynamicProjection() { + String query = deriveQueryFromMethod("findDynamicallyProjectedBy", PersonProjection.class); assertThat(query).isEqualTo("SELECT * FROM person;"); } + @Test // DATACASS-479 + public void usesProjectionQueryHiddenField() { + + String query = deriveQueryFromMethod("findPersonProjectedByNickname", "foo"); + + assertThat(query).isEqualTo("SELECT * FROM person WHERE nickname='foo';"); + } + @Test // DATACASS-357 public void shouldDeriveFieldInCollectionQuery() { @@ -181,11 +192,10 @@ public class PartTreeCassandraQueryUnitTests { PartTreeCassandraQuery partTreeQuery = createQueryForMethod(repositoryInterface, method, types); - CassandraParameterAccessor accessor = - new CassandraParametersParameterAccessor(partTreeQuery.getQueryMethod(), args); + CassandraParameterAccessor accessor = new CassandraParametersParameterAccessor(partTreeQuery.getQueryMethod(), + args); - return partTreeQuery.createQuery( - new ConvertingParameterAccessor(mockCassandraOperations.getConverter(), accessor)); + return partTreeQuery.createQuery(new ConvertingParameterAccessor(mockCassandraOperations.getConverter(), accessor)); } private PartTreeCassandraQuery createQueryForMethod(Class repositoryInterface, String methodName, @@ -238,7 +248,7 @@ public class PartTreeCassandraQueryUnitTests { @AllowFiltering Person findByFirstname(String firstname); - PersonProjection findPersonProjectedBy(); + PersonProjection findPersonProjectedByNickname(String nickname); T findDynamicallyProjectedBy(Class type);