Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

In an immutable @ConfigurationProperties object nested properties object is null when no nested property specified #21281

Closed
jannis-baratheon opened this issue Apr 30, 2020 · 2 comments
Labels
status: duplicate A duplicate of another issue

Comments

@jannis-baratheon
Copy link

jannis-baratheon commented Apr 30, 2020

Version information

Spring-boot: 2.2.6.RELEASE

Reproduction

I have an immutable @ConfigurationProperties class with nested properties:

package com.example.demo;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConstructorBinding;
import org.springframework.boot.context.properties.bind.DefaultValue;

@ConfigurationProperties
@ConstructorBinding
public class NestedConfigurationProperties {

	private final NestedProperties nested;
	private final String property;

	public NestedConfigurationProperties(
			NestedProperties nested,
			String property) {
		this.nested = nested;
		this.property = property;
	}

	public NestedProperties getNested() {
		return nested;
	}

	public String getProperty() {
		return property;
	}

	public static class NestedProperties {
		private final String nestedProperty;

		public NestedProperties(@DefaultValue("default_value") String nestedProperty) {
			this.nestedProperty = nestedProperty;
		}

		public String getNestedProperty() {
			return nestedProperty;
		}
	}
}

When I bind the class without specifying a value for the nested property the nested properties holder object is null. A test illustrating my expectations:

package com.example.demo;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.HashMap;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.springframework.boot.context.properties.bind.BindResult;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.context.properties.source.MapConfigurationPropertySource;

public class PropertiesTest {

	@Test
	void nestedPropertiesAreNotNull() {
		Map<String, String> properties = new HashMap<>();
		properties.put("property", "some value");
		Binder binder = new Binder(new MapConfigurationPropertySource(properties));

		BindResult<NestedConfigurationProperties> bindResult =
				binder.bind("", Bindable.of(NestedConfigurationProperties.class));

		assertThat(bindResult.get().getNested()).isNotNull();
	}
}

Unless I set a value for a nested property (properties.put("nested.nested_property", "some value")) the NestedConfigurationProperties#nested field is null.

Expected result

The nested properties object is never null when binding the top-level properties.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Apr 30, 2020
@mbhave
Copy link
Contributor

mbhave commented Apr 30, 2020

This is a duplicate of #18917. The fix for that will be available in Spring Boot 2.2.7. An empty @DefaultValue on the constructor parameter indicates the property should never be null even when nothing was bound to it. You can give it a try with the 2.2.7 snapshots.

@mbhave mbhave closed this as completed Apr 30, 2020
@mbhave mbhave added status: duplicate A duplicate of another issue and removed status: waiting-for-triage An issue we've not yet triaged labels Apr 30, 2020
@jannis-baratheon
Copy link
Author

Thanks @mbhave.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: duplicate A duplicate of another issue
Projects
None yet
Development

No branches or pull requests

3 participants