Read correct domain type when returning interface type from domain type hierarchy.
We now read the correct type to read (domain type) when a repository query method declares an interface type that is implemented by the domain type. Closes #1335
This commit is contained in:
@@ -107,7 +107,7 @@ public abstract class AbstractCassandraQuery extends CassandraRepositoryQuerySup
|
||||
CassandraReturnedType returnedType = new CassandraReturnedType(resultProcessor.getReturnedType(),
|
||||
getOperations().getConverter().getCustomConversions());
|
||||
|
||||
return returnedType.isProjecting() ? returnedType.getDomainType() : returnedType.getReturnedType();
|
||||
return returnedType.getResultType();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -103,7 +103,7 @@ public abstract class AbstractReactiveCassandraQuery extends CassandraRepository
|
||||
CassandraReturnedType returnedType = new CassandraReturnedType(resultProcessor.getReturnedType(),
|
||||
getRequiredConverter(getReactiveCassandraOperations()).getCustomConversions());
|
||||
|
||||
return (returnedType.isProjecting() ? returnedType.getDomainType() : returnedType.getReturnedType());
|
||||
return returnedType.getResultType();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,7 +19,6 @@ import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.data.cassandra.core.CassandraOperations;
|
||||
import org.springframework.data.cassandra.core.mapping.CassandraMappingContext;
|
||||
import org.springframework.data.cassandra.core.mapping.CassandraPersistentEntity;
|
||||
@@ -104,7 +103,22 @@ public abstract class CassandraRepositoryQuerySupport implements RepositoryQuery
|
||||
this.customConversions = customConversions;
|
||||
}
|
||||
|
||||
boolean isProjecting() {
|
||||
public Class<?> getResultType() {
|
||||
|
||||
if (isProjecting()) {
|
||||
return returnedType.getDomainType();
|
||||
}
|
||||
|
||||
Class<?> typeToRead = returnedType.getTypeToRead();
|
||||
|
||||
if (typeToRead == null) {
|
||||
return returnedType.getReturnedType();
|
||||
}
|
||||
|
||||
return typeToRead;
|
||||
}
|
||||
|
||||
private boolean isProjecting() {
|
||||
|
||||
if (!this.returnedType.isProjecting()) {
|
||||
return false;
|
||||
@@ -124,13 +138,5 @@ public abstract class CassandraRepositoryQuerySupport implements RepositoryQuery
|
||||
// Don't apply projection on Cassandra simple types
|
||||
return !this.customConversions.isSimpleType(this.returnedType.getReturnedType());
|
||||
}
|
||||
|
||||
Class<?> getDomainType() {
|
||||
return this.returnedType.getDomainType();
|
||||
}
|
||||
|
||||
Class<?> getReturnedType() {
|
||||
return this.returnedType.getReturnedType();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.cassandra.repository.query;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.data.cassandra.core.CassandraOperations;
|
||||
import org.springframework.data.cassandra.core.convert.MappingCassandraConverter;
|
||||
import org.springframework.data.cassandra.core.mapping.CassandraMappingContext;
|
||||
import org.springframework.data.cassandra.repository.CassandraRepository;
|
||||
import org.springframework.data.projection.ProjectionFactory;
|
||||
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
|
||||
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link AbstractCassandraQuery}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class AbstractCassandraQueryUnitTests {
|
||||
|
||||
CassandraMappingContext context = new CassandraMappingContext();
|
||||
CassandraOperations operations = mock(CassandraOperations.class);
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
when(operations.getConverter()).thenReturn(new MappingCassandraConverter(context));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldResolveDomainTypeForReturnedInterfaceInHierarchy() throws Exception {
|
||||
|
||||
DefaultRepositoryMetadata metadata = new DefaultRepositoryMetadata(MyRepository.class);
|
||||
|
||||
ProjectionFactory factory = new SpelAwareProxyProjectionFactory();
|
||||
CassandraQueryMethod method = new CassandraQueryMethod(MyRepository.class.getMethod("findBy"), metadata, factory,
|
||||
context);
|
||||
|
||||
PartTreeCassandraQuery cq = new PartTreeCassandraQuery(method, operations);
|
||||
cq.execute(new Object[0]);
|
||||
|
||||
verify(operations).select(any(com.datastax.oss.driver.api.core.cql.Statement.class), eq(MyClass.class));
|
||||
}
|
||||
|
||||
interface MyInterface {
|
||||
|
||||
}
|
||||
|
||||
static class MyClass implements MyInterface {
|
||||
|
||||
}
|
||||
|
||||
interface MyRepository extends CassandraRepository<MyClass, String> {
|
||||
|
||||
Optional<MyInterface> findBy();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user