From f9962fe31a4089160984750d1b711ed471b88da7 Mon Sep 17 00:00:00 2001 From: Florian Cramer Date: Thu, 13 Apr 2023 12:48:56 +0200 Subject: [PATCH] Support Validation for fields the type of which is not a PersistentEntity --- .../data/rest/core/ValidationErrors.java | 9 +++++- .../rest/core/ValidationErrorsUnitTests.java | 29 +++++++++++++++++-- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/ValidationErrors.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/ValidationErrors.java index c4c11652a..34d79b96e 100644 --- a/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/ValidationErrors.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/ValidationErrors.java @@ -18,6 +18,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Iterator; +import java.util.Optional; import org.springframework.beans.BeansException; import org.springframework.beans.ConfigurablePropertyAccessor; @@ -39,6 +40,7 @@ * * @author Jon Brisbin * @author Oliver Gierke + * @author Florian Cramer */ public class ValidationErrors extends AbstractPropertyBindingResult { @@ -92,7 +94,12 @@ public Object getPropertyValue(String propertyName) throws BeansException { */ private Object lookupValueOn(Object value, String segment) { - PersistentProperty property = entities.getPersistentEntity(value.getClass()) // + Optional>> entity = entities.getPersistentEntity(value.getClass()); + if (!entity.isPresent()) { + return new DirectFieldAccessor(value).getPropertyValue(segment); + } + + PersistentProperty property = entity // .map(it -> it.getPersistentProperty(PropertyAccessorUtils.getPropertyName(segment))) // .orElseThrow(() -> new NotReadablePropertyException(value.getClass(), segment)); diff --git a/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/ValidationErrorsUnitTests.java b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/ValidationErrorsUnitTests.java index 1dfb356c0..ad24f722e 100755 --- a/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/ValidationErrorsUnitTests.java +++ b/spring-data-rest-core/src/test/java/org/springframework/data/rest/core/ValidationErrorsUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 original author or authors. + * Copyright 2016-2023 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. @@ -24,14 +24,18 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.NotReadablePropertyException; +import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentEntity; +import org.springframework.data.keyvalue.core.mapping.KeyValuePersistentProperty; import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext; import org.springframework.data.mapping.context.PersistentEntities; +import org.springframework.data.util.TypeInformation; import org.springframework.validation.Errors; /** * Unit tests for {@link ValidationErrors}. * * @author Oliver Gierke + * @author Florian Cramer */ class ValidationErrorsUnitTests { @@ -40,7 +44,7 @@ class ValidationErrorsUnitTests { @BeforeEach void setUp() { - KeyValueMappingContext context = new KeyValueMappingContext<>(); + KeyValueMappingContext context = new TestKeyValueMappingContext<>(); context.getPersistentEntity(Foo.class); this.entities = new PersistentEntities(Arrays.asList(context)); @@ -71,6 +75,14 @@ void returnsNullForPropertyValue() { assertThat(errors.getFieldValue("bar")).isNull(); } + @Test // GH-2252 + void getsTheNestedFieldsValueForNonPersistentEntity() { + + ValidationErrors errors = new ValidationErrors(new Foo(), entities); + + assertThat(errors.getFieldValue("qux.field")).isEqualTo("World"); + } + private static void expectedErrorBehavior(Errors errors) { assertThat(errors.getFieldValue("bars")).isNotNull(); @@ -88,9 +100,22 @@ private static void expectedErrorBehavior(Errors errors) { static class Foo { List bars = Collections.singletonList(new Bar()); Bar bar = null; + Qux qux = new Qux(); } static class Bar { String field = "Hello"; } + + static class Qux { + String field = "World"; + } + + static class TestKeyValueMappingContext, P extends KeyValuePersistentProperty

> extends KeyValueMappingContext { + + @Override + protected boolean shouldCreatePersistentEntityFor(TypeInformation type) { + return Qux.class != type.getType() && super.shouldCreatePersistentEntityFor(type); + } + } }