Skip to content

Commit 515bffc

Browse files
committed
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
1 parent 745ae59 commit 515bffc

File tree

4 files changed

+92
-12
lines changed

4 files changed

+92
-12
lines changed

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/AbstractCassandraQuery.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ private Class<?> resolveResultType(ResultProcessor resultProcessor) {
107107
CassandraReturnedType returnedType = new CassandraReturnedType(resultProcessor.getReturnedType(),
108108
getOperations().getConverter().getCustomConversions());
109109

110-
return returnedType.isProjecting() ? returnedType.getDomainType() : returnedType.getReturnedType();
110+
return returnedType.getResultType();
111111
}
112112

113113
/**

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/AbstractReactiveCassandraQuery.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ private Class<?> resolveResultType(ResultProcessor resultProcessor) {
103103
CassandraReturnedType returnedType = new CassandraReturnedType(resultProcessor.getReturnedType(),
104104
getRequiredConverter(getReactiveCassandraOperations()).getCustomConversions());
105105

106-
return (returnedType.isProjecting() ? returnedType.getDomainType() : returnedType.getReturnedType());
106+
return returnedType.getResultType();
107107
}
108108

109109
/**

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraRepositoryQuerySupport.java

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
import org.apache.commons.logging.Log;
2121
import org.apache.commons.logging.LogFactory;
22-
2322
import org.springframework.data.cassandra.core.CassandraOperations;
2423
import org.springframework.data.cassandra.core.mapping.CassandraMappingContext;
2524
import org.springframework.data.cassandra.core.mapping.CassandraPersistentEntity;
@@ -104,7 +103,22 @@ class CassandraReturnedType {
104103
this.customConversions = customConversions;
105104
}
106105

107-
boolean isProjecting() {
106+
public Class<?> getResultType() {
107+
108+
if (isProjecting()) {
109+
return returnedType.getDomainType();
110+
}
111+
112+
Class<?> typeToRead = returnedType.getTypeToRead();
113+
114+
if (typeToRead == null) {
115+
return returnedType.getReturnedType();
116+
}
117+
118+
return typeToRead;
119+
}
120+
121+
private boolean isProjecting() {
108122

109123
if (!this.returnedType.isProjecting()) {
110124
return false;
@@ -124,13 +138,5 @@ boolean isProjecting() {
124138
// Don't apply projection on Cassandra simple types
125139
return !this.customConversions.isSimpleType(this.returnedType.getReturnedType());
126140
}
127-
128-
Class<?> getDomainType() {
129-
return this.returnedType.getDomainType();
130-
}
131-
132-
Class<?> getReturnedType() {
133-
return this.returnedType.getReturnedType();
134-
}
135141
}
136142
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.cassandra.repository.query;
17+
18+
import static org.mockito.Mockito.*;
19+
20+
import java.util.Optional;
21+
22+
import org.junit.jupiter.api.BeforeEach;
23+
import org.junit.jupiter.api.Test;
24+
import org.springframework.data.cassandra.core.CassandraOperations;
25+
import org.springframework.data.cassandra.core.convert.MappingCassandraConverter;
26+
import org.springframework.data.cassandra.core.mapping.CassandraMappingContext;
27+
import org.springframework.data.cassandra.repository.CassandraRepository;
28+
import org.springframework.data.projection.ProjectionFactory;
29+
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
30+
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
31+
32+
/**
33+
* Unit tests for {@link AbstractCassandraQuery}.
34+
*
35+
* @author Mark Paluch
36+
*/
37+
public class AbstractCassandraQueryUnitTests {
38+
39+
CassandraMappingContext context = new CassandraMappingContext();
40+
CassandraOperations operations = mock(CassandraOperations.class);
41+
42+
@BeforeEach
43+
void setUp() {
44+
when(operations.getConverter()).thenReturn(new MappingCassandraConverter(context));
45+
}
46+
47+
@Test
48+
void shouldResolveDomainTypeForReturnedInterfaceInHierarchy() throws Exception {
49+
50+
DefaultRepositoryMetadata metadata = new DefaultRepositoryMetadata(MyRepository.class);
51+
52+
ProjectionFactory factory = new SpelAwareProxyProjectionFactory();
53+
CassandraQueryMethod method = new CassandraQueryMethod(MyRepository.class.getMethod("findBy"), metadata, factory,
54+
context);
55+
56+
PartTreeCassandraQuery cq = new PartTreeCassandraQuery(method, operations);
57+
cq.execute(new Object[0]);
58+
59+
verify(operations).select(any(com.datastax.oss.driver.api.core.cql.Statement.class), eq(MyClass.class));
60+
}
61+
62+
interface MyInterface {
63+
64+
}
65+
66+
static class MyClass implements MyInterface {
67+
68+
}
69+
70+
interface MyRepository extends CassandraRepository<MyClass, String> {
71+
72+
Optional<MyInterface> findBy();
73+
}
74+
}

0 commit comments

Comments
 (0)