Skip to content

Commit 5afcb9e

Browse files
Fix Optional handling in query creation and result processing.
1 parent f659210 commit 5afcb9e

File tree

5 files changed

+76
-0
lines changed

5 files changed

+76
-0
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoMappingContext.java

+6
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.springframework.data.mapping.model.Property;
2727
import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy;
2828
import org.springframework.data.mapping.model.SimpleTypeHolder;
29+
import org.springframework.data.util.NullableWrapperConverters;
2930
import org.springframework.data.util.TypeInformation;
3031
import org.springframework.lang.Nullable;
3132

@@ -69,6 +70,11 @@ public void setFieldNamingStrategy(@Nullable FieldNamingStrategy fieldNamingStra
6970
*/
7071
@Override
7172
protected boolean shouldCreatePersistentEntityFor(TypeInformation<?> type) {
73+
74+
if(NullableWrapperConverters.supports(type.getType())) {
75+
return false;
76+
}
77+
7278
return !MongoSimpleTypes.HOLDER.isSimpleType(type.getType()) && !AbstractMap.class.isAssignableFrom(type.getType());
7379
}
7480

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/MongoMappingContextUnitTests.java

+31
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.Collections;
2323
import java.util.Locale;
2424
import java.util.Map;
25+
import java.util.Optional;
2526

2627
import org.junit.jupiter.api.Test;
2728
import org.junit.jupiter.api.extension.ExtendWith;
@@ -35,6 +36,7 @@
3536
import org.springframework.data.mapping.model.FieldNamingStrategy;
3637

3738
import com.mongodb.DBRef;
39+
import org.springframework.data.util.TypeInformation;
3840

3941
/**
4042
* Unit tests for {@link MongoMappingContext}.
@@ -173,6 +175,26 @@ void shouldNotCreateEntityForEnum() {
173175
assertThat(context.getPersistentEntity(ChronoUnit.class)).isNull();
174176
}
175177

178+
@Test // GH-3656
179+
void shouldNotCreateEntityForOptionalGetter() {
180+
181+
MongoMappingContext context = new MongoMappingContext();
182+
MongoPersistentEntity<?> entity = context.getRequiredPersistentEntity(InterfaceWithMethodReturningOptional.class);
183+
184+
assertThat(context.getPersistentEntities()).map(it -> it.getType()).doesNotContain((Class)
185+
Optional.class).contains((Class)Person.class);
186+
}
187+
188+
@Test // GH-3656
189+
void shouldNotCreateEntityForOptionalField() {
190+
191+
MongoMappingContext context = new MongoMappingContext();
192+
MongoPersistentEntity<?> entity = context.getRequiredPersistentEntity(ClassWithOptionalField.class);
193+
194+
assertThat(context.getPersistentEntities()).map(it -> it.getType()).doesNotContain((Class)
195+
Optional.class).contains((Class)Person.class);
196+
}
197+
176198
public class SampleClass {
177199

178200
Map<String, SampleClass> children;
@@ -244,4 +266,13 @@ class ClassWithChronoUnit {
244266

245267
ChronoUnit unit;
246268
}
269+
270+
interface InterfaceWithMethodReturningOptional {
271+
272+
Optional<Person> getPerson();
273+
}
274+
275+
class ClassWithOptionalField {
276+
Optional<Person> person;
277+
}
247278
}

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java

+13
Original file line numberDiff line numberDiff line change
@@ -1460,4 +1460,17 @@ void executesQueryWithDocumentReferenceCorrectly() {
14601460
List<Person> result = repository.findBySpiritAnimal(dave);
14611461
assertThat(result).map(Person::getId).containsExactly(josh.getId());
14621462
}
1463+
1464+
@Test //GH-3656
1465+
void resultProjectionWithOptionalIsExcecutedCorrectly() {
1466+
1467+
carter.setAddress(new Address("batman", "robin", "gotham"));
1468+
repository.save(carter);
1469+
1470+
PersonSummaryWithOptional result = repository.findSummaryWithOptionalByLastname("Beauford");
1471+
1472+
assertThat(result).isNotNull();
1473+
assertThat(result.getAddress()).isPresent();
1474+
assertThat(result.getFirstname()).contains("Carter");
1475+
}
14631476
}

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepository.java

+2
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,8 @@ Page<Person> findByCustomQueryLastnameAndAddressStreetInList(String lastname, Li
307307
// DATAMONGO-1030
308308
PersonSummaryDto findSummaryByLastname(String lastname);
309309

310+
PersonSummaryWithOptional findSummaryWithOptionalByLastname(String lastname);
311+
310312
@Query("{ ?0 : ?1 }")
311313
List<Person> findByKeyValue(String key, String value);
312314

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright 2021 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.mongodb.repository;
17+
18+
import java.util.Optional;
19+
20+
public interface PersonSummaryWithOptional {
21+
22+
Optional<Address> getAddress();
23+
Optional<String> getFirstname();
24+
}

0 commit comments

Comments
 (0)