diff --git a/spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java b/spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java index cd910621fb..16ab258a14 100644 --- a/spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -422,9 +422,12 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA } return; } - else { - throw createNotWritablePropertyException(tokens.canonicalName); + if (this.suppressNotWritablePropertyException) { + // Optimization for common ignoreUnknown=true scenario since the + // exception would be caught and swallowed higher up anyway... + return; } + throw createNotWritablePropertyException(tokens.canonicalName); } Object oldValue = null; diff --git a/spring-beans/src/main/java/org/springframework/beans/AbstractPropertyAccessor.java b/spring-beans/src/main/java/org/springframework/beans/AbstractPropertyAccessor.java index cd2e7e5160..1d6b5f48ea 100644 --- a/spring-beans/src/main/java/org/springframework/beans/AbstractPropertyAccessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/AbstractPropertyAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 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. @@ -40,6 +40,8 @@ public abstract class AbstractPropertyAccessor extends TypeConverterSupport impl private boolean autoGrowNestedPaths = false; + boolean suppressNotWritablePropertyException = false; + @Override public void setExtractOldValueForEditor(boolean extractOldValueForEditor) { @@ -89,30 +91,41 @@ public abstract class AbstractPropertyAccessor extends TypeConverterSupport impl List propertyAccessExceptions = null; List propertyValues = (pvs instanceof MutablePropertyValues ? ((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues())); - for (PropertyValue pv : propertyValues) { - try { - // This method may throw any BeansException, which won't be caught + + if (ignoreUnknown) { + this.suppressNotWritablePropertyException = true; + } + try { + for (PropertyValue pv : propertyValues) { + // setPropertyValue may throw any BeansException, which won't be caught // here, if there is a critical failure such as no matching field. // We can attempt to deal only with less serious exceptions. - setPropertyValue(pv); - } - catch (NotWritablePropertyException ex) { - if (!ignoreUnknown) { - throw ex; + try { + setPropertyValue(pv); } - // Otherwise, just ignore it and continue... - } - catch (NullValueInNestedPathException ex) { - if (!ignoreInvalid) { - throw ex; + catch (NotWritablePropertyException ex) { + if (!ignoreUnknown) { + throw ex; + } + // Otherwise, just ignore it and continue... } - // Otherwise, just ignore it and continue... - } - catch (PropertyAccessException ex) { - if (propertyAccessExceptions == null) { - propertyAccessExceptions = new ArrayList<>(); + catch (NullValueInNestedPathException ex) { + if (!ignoreInvalid) { + throw ex; + } + // Otherwise, just ignore it and continue... + } + catch (PropertyAccessException ex) { + if (propertyAccessExceptions == null) { + propertyAccessExceptions = new ArrayList<>(); + } + propertyAccessExceptions.add(ex); } - propertyAccessExceptions.add(ex); + } + } + finally { + if (ignoreUnknown) { + this.suppressNotWritablePropertyException = false; } }