Skip to content

Commit 2143ba4

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 9c12df9 commit 2143ba4

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
@@ -110,7 +110,7 @@ private Class<?> resolveResultType(ResultProcessor resultProcessor) {
110110
CassandraReturnedType returnedType = new CassandraReturnedType(resultProcessor.getReturnedType(),
111111
getOperations().getConverter().getCustomConversions());
112112

113-
return returnedType.isProjecting() ? returnedType.getDomainType() : returnedType.getReturnedType();
113+
return returnedType.getResultType();
114114
}
115115

116116
/**

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
@@ -109,7 +109,7 @@ private Class<?> resolveResultType(ResultProcessor resultProcessor) {
109109
CassandraReturnedType returnedType = new CassandraReturnedType(resultProcessor.getReturnedType(),
110110
getRequiredConverter(getReactiveCassandraOperations()).getCustomConversions());
111111

112-
return (returnedType.isProjecting() ? returnedType.getDomainType() : returnedType.getReturnedType());
112+
return returnedType.getResultType();
113113
}
114114

115115
/**

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;
@@ -107,7 +106,22 @@ class CassandraReturnedType {
107106
this.customConversions = customConversions;
108107
}
109108

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

112126
if (!this.returnedType.isProjecting()) {
113127
return false;
@@ -127,13 +141,5 @@ boolean isProjecting() {
127141
// Don't apply projection on Cassandra simple types
128142
return !this.customConversions.isSimpleType(this.returnedType.getReturnedType());
129143
}
130-
131-
Class<?> getDomainType() {
132-
return this.returnedType.getDomainType();
133-
}
134-
135-
Class<?> getReturnedType() {
136-
return this.returnedType.getReturnedType();
137-
}
138144
}
139145
}
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)