Skip to content

AutoGrow not applied for nested map values #32154

Open
@ejnarvala

Description

@ejnarvala

Affects: 6.0.8


Language: Kotlin
Spring Version: 6.0.8

I am using data binding for parsing form data into a form object. When using a singly nested map (Map<String, Map<String, String>), I find that using the key property[map1key][map2key] works as expected to set the nested value, but when adding another layer, e.g. Map<String, Map<String, Map<String, String>>> with key property[map1key][map2key][map3key] this fails with an exception cannot access indexed value of property referenced in indexed property path nested map.

Looking into the source code, I believe I tracked it down to the AbstractNestablePropertyAccessor.getPropertyValue(PropertyTokenHolder tokens) method which seems to only set the default value on the first token which explains why this works for a singly nested map but not a double or greater one. I suspect this affects any type of auto growing collection as well.

relevant snippet:

			if (tokens.keys != null) {
				if (value == null) {
					if (isAutoGrowNestedPaths()) {
						value = setDefaultValue(new PropertyTokenHolder(tokens.actualName));
					}
					else {
						throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + propertyName,
								"Cannot access indexed value of property referenced in indexed " +
										"property path '" + propertyName + "': returned null");
					}
				}
				StringBuilder indexedPropertyName = new StringBuilder(tokens.actualName);
				// apply indexes and map keys
				for (int i = 0; i < tokens.keys.length; i++) {
					String key = tokens.keys[i];
					if (value == null) {
						throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + propertyName,
								"Cannot access indexed value of property referenced in indexed " +
										"property path '" + propertyName + "': returned null");
					}

As a workaround, I'm using a single map with a custom key that I deserialize manually and then convert to a nested map in application code, but it would be nice if this was supported as part of the data binding.

Metadata

Metadata

Assignees

No one assigned

    Labels

    in: coreIssues in core modules (aop, beans, core, context, expression)type: enhancementA general enhancement

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions