diff --git a/src/main/java/org/springframework/data/mapping/PropertyPath.java b/src/main/java/org/springframework/data/mapping/PropertyPath.java index 7596792ed..f5e6f1e1f 100644 --- a/src/main/java/org/springframework/data/mapping/PropertyPath.java +++ b/src/main/java/org/springframework/data/mapping/PropertyPath.java @@ -195,6 +195,21 @@ public class PropertyPath implements Streamable { return isCollection; } + /** + * Returns the {@link PropertyPath} for the path nested under the current property. + * + * @param path must not be {@literal null} or empty. + * @return will never be {@literal null}. + */ + public PropertyPath nested(String path) { + + Assert.hasText(path, "Path must not be null or empty!"); + + String lookup = toDotPath().concat(".").concat(path); + + return PropertyPath.from(lookup, owningType); + } + /* * (non-Javadoc) * @see java.lang.Iterable#iterator() diff --git a/src/test/java/org/springframework/data/mapping/PropertyPathUnitTests.java b/src/test/java/org/springframework/data/mapping/PropertyPathUnitTests.java index c9653e288..71853d5e0 100755 --- a/src/test/java/org/springframework/data/mapping/PropertyPathUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/PropertyPathUnitTests.java @@ -355,6 +355,20 @@ public class PropertyPathUnitTests { assertThat(from("user.name", Bar.class).getLeafType()).isEqualTo(String.class); } + @Test // DATACMNS-1199 + public void createsNestedPropertyPath() { + assertThat(from("user", Bar.class).nested("name")).isEqualTo(from("user.name", Bar.class)); + } + + @Test // DATACMNS-1199 + public void rejectsNonExistantNestedPath() { + + assertThatExceptionOfType(PropertyReferenceException.class) // + .isThrownBy(() -> from("user", Bar.class).nested("nonexistant")) // + .withMessageContaining("nonexistant") // + .withMessageContaining("Bar.user"); + } + private class Foo { String userName;