Browse Source

Avoid duplicate context nesting to properly convert nested projections.

Closes: #4609
Original pull request: #4616
pull/4655/head
Christoph Strobl 2 years ago committed by Mark Paluch
parent
commit
48b26368af
No known key found for this signature in database
GPG Key ID: 55BC6374BAA9D973
  1. 5
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java
  2. 24
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java
  3. 62
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java

5
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java

@ -595,7 +595,6 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App @@ -595,7 +595,6 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
}
ConversionContext propertyContext = context.forProperty(prop);
MongoDbPropertyValueProvider valueProviderToUse = valueProvider.withContext(propertyContext);
if (prop.isAssociation()) {
@ -623,7 +622,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App @@ -623,7 +622,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
continue;
}
accessor.setProperty(prop, valueProviderToUse.getPropertyValue(prop));
accessor.setProperty(prop, valueProvider.getPropertyValue(prop));
}
}
@ -2436,6 +2435,8 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App @@ -2436,6 +2435,8 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
this.returnedTypeDescriptor = projection;
}
@Override
public ConversionContext forProperty(String name) {

24
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java

@ -2554,6 +2554,30 @@ public class MongoTemplateTests { @@ -2554,6 +2554,30 @@ public class MongoTemplateTests {
assertThat(projection.getName()).isEqualTo("Walter");
}
@Test // GH-4609
public void shouldReadNestedProjection() {
MyPerson walter = new MyPerson("Walter");
walter.address = new Address("spring", "data");
template.save(walter);
PersonPWA result = template.query(MyPerson.class)
.as(PersonPWA.class)
.matching(where("id").is(walter.id))
.firstValue();
assertThat(result.getAddress().getCity()).isEqualTo("data");
}
interface PersonPWA {
String getName();
AdressProjection getAddress();
}
interface AdressProjection {
String getCity();
}
@Test // GH-4300
public void findAndReplaceShouldAllowNativeDomainTypesAndReturnAProjection() {

62
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java

@ -2851,6 +2851,44 @@ class MappingMongoConverterUnitTests { @@ -2851,6 +2851,44 @@ class MappingMongoConverterUnitTests {
assertThat(person.getAddresses()).extracting(AddressProjection::getStreet).hasSize(1).containsOnly("hwy");
}
@Test // GH-4609
void projectShouldReadNestedInterfaceProjection() {
org.bson.Document source = new org.bson.Document("foo", "spring").append("address",
new org.bson.Document("s", "data").append("city", "mongodb"));
EntityProjectionIntrospector introspector = EntityProjectionIntrospector.create(converter.getProjectionFactory(),
EntityProjectionIntrospector.ProjectionPredicate.typeHierarchy()
.and((target, underlyingType) -> !converter.conversions.isSimpleType(target)),
mappingContext);
EntityProjection<WithNestedInterfaceProjection, Person> projection = introspector.introspect(WithNestedInterfaceProjection.class,
Person.class);
WithNestedInterfaceProjection person = converter.project(projection, source);
assertThat(person.getFirstname()).isEqualTo("spring");
assertThat(person.getAddress().getStreet()).isEqualTo("data");
}
@Test // GH-4609
void projectShouldReadNestedDtoProjection() {
org.bson.Document source = new org.bson.Document("foo", "spring").append("address",
new org.bson.Document("s", "data").append("city", "mongodb"));
EntityProjectionIntrospector introspector = EntityProjectionIntrospector.create(converter.getProjectionFactory(),
EntityProjectionIntrospector.ProjectionPredicate.typeHierarchy()
.and((target, underlyingType) -> !converter.conversions.isSimpleType(target)),
mappingContext);
EntityProjection<WithNestedDtoProjection, Person> projection = introspector.introspect(WithNestedDtoProjection.class,
Person.class);
WithNestedDtoProjection person = converter.project(projection, source);
assertThat(person.getFirstname()).isEqualTo("spring");
assertThat(person.getAddress().getStreet()).isEqualTo("data");
}
@Test // GH-2860
void projectShouldReadProjectionWithNestedEntity() {
@ -3206,6 +3244,7 @@ class MappingMongoConverterUnitTests { @@ -3206,6 +3244,7 @@ class MappingMongoConverterUnitTests {
String lastname;
Set<Address> addresses;
Address address;
Person() {
@ -3248,6 +3287,16 @@ class MappingMongoConverterUnitTests { @@ -3248,6 +3287,16 @@ class MappingMongoConverterUnitTests {
Set<AddressProjection> getAddresses();
}
interface WithNestedInterfaceProjection {
String getFirstname();
AddressProjection getAddress();
}
interface WithNestedDtoProjection {
String getFirstname();
AddressDto getAddress();
}
interface ProjectionWithNestedEntity {
Set<Address> getAddresses();
@ -3258,6 +3307,19 @@ class MappingMongoConverterUnitTests { @@ -3258,6 +3307,19 @@ class MappingMongoConverterUnitTests {
String getStreet();
}
class AddressDto {
String street;
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
}
static class PersonDto {
LocalDate birthDate;

Loading…
Cancel
Save