Fix Optional handling in query creation and result processing.

Original pull request: #3687.
Resolves #3656
This commit is contained in:
Christoph Strobl
2021-06-23 15:45:14 +02:00
committed by Mark Paluch
parent 4f65bb0810
commit 403f0019d5
5 changed files with 76 additions and 0 deletions

View File

@@ -26,6 +26,7 @@ import org.springframework.data.mapping.model.FieldNamingStrategy;
import org.springframework.data.mapping.model.Property;
import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.util.NullableWrapperConverters;
import org.springframework.data.util.TypeInformation;
import org.springframework.lang.Nullable;
@@ -69,6 +70,11 @@ public class MongoMappingContext extends AbstractMappingContext<MongoPersistentE
*/
@Override
protected boolean shouldCreatePersistentEntityFor(TypeInformation<?> type) {
if(NullableWrapperConverters.supports(type.getType())) {
return false;
}
return !MongoSimpleTypes.HOLDER.isSimpleType(type.getType()) && !AbstractMap.class.isAssignableFrom(type.getType());
}

View File

@@ -22,6 +22,7 @@ import java.util.AbstractMap;
import java.util.Collections;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -35,6 +36,7 @@ import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.model.FieldNamingStrategy;
import com.mongodb.DBRef;
import org.springframework.data.util.TypeInformation;
/**
* Unit tests for {@link MongoMappingContext}.
@@ -173,6 +175,26 @@ public class MongoMappingContextUnitTests {
assertThat(context.getPersistentEntity(ChronoUnit.class)).isNull();
}
@Test // GH-3656
void shouldNotCreateEntityForOptionalGetter() {
MongoMappingContext context = new MongoMappingContext();
MongoPersistentEntity<?> entity = context.getRequiredPersistentEntity(InterfaceWithMethodReturningOptional.class);
assertThat(context.getPersistentEntities()).map(it -> it.getType()).doesNotContain((Class)
Optional.class).contains((Class)Person.class);
}
@Test // GH-3656
void shouldNotCreateEntityForOptionalField() {
MongoMappingContext context = new MongoMappingContext();
MongoPersistentEntity<?> entity = context.getRequiredPersistentEntity(ClassWithOptionalField.class);
assertThat(context.getPersistentEntities()).map(it -> it.getType()).doesNotContain((Class)
Optional.class).contains((Class)Person.class);
}
public class SampleClass {
Map<String, SampleClass> children;
@@ -244,4 +266,13 @@ public class MongoMappingContextUnitTests {
ChronoUnit unit;
}
interface InterfaceWithMethodReturningOptional {
Optional<Person> getPerson();
}
class ClassWithOptionalField {
Optional<Person> person;
}
}

View File

@@ -1460,4 +1460,17 @@ public abstract class AbstractPersonRepositoryIntegrationTests {
List<Person> result = repository.findBySpiritAnimal(dave);
assertThat(result).map(Person::getId).containsExactly(josh.getId());
}
@Test //GH-3656
void resultProjectionWithOptionalIsExcecutedCorrectly() {
carter.setAddress(new Address("batman", "robin", "gotham"));
repository.save(carter);
PersonSummaryWithOptional result = repository.findSummaryWithOptionalByLastname("Beauford");
assertThat(result).isNotNull();
assertThat(result.getAddress()).isPresent();
assertThat(result.getFirstname()).contains("Carter");
}
}

View File

@@ -307,6 +307,8 @@ public interface PersonRepository extends MongoRepository<Person, String>, Query
// DATAMONGO-1030
PersonSummaryDto findSummaryByLastname(String lastname);
PersonSummaryWithOptional findSummaryWithOptionalByLastname(String lastname);
@Query("{ ?0 : ?1 }")
List<Person> findByKeyValue(String key, String value);

View File

@@ -0,0 +1,24 @@
/*
* Copyright 2021 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.mongodb.repository;
import java.util.Optional;
public interface PersonSummaryWithOptional {
Optional<Address> getAddress();
Optional<String> getFirstname();
}