{"action":"closed","issue":{"url":"https://api.github.com/repos/spring-projects/spring-boot/issues/3539","labels_url":"https://api.github.com/repos/spring-projects/spring-boot/issues/3539/labels{/name}","comments_url":"https://api.github.com/repos/spring-projects/spring-boot/issues/3539/comments","events_url":"https://api.github.com/repos/spring-projects/spring-boot/issues/3539/events","html_url":"https://github.com/spring-projects/spring-boot/issues/3539","id":95663078,"number":3539,"title":"Relaxed binding does not work properly for nested properties","user":{"login":"altery","id":2925993,"avatar_url":"https://avatars.githubusercontent.com/u/2925993?v=3","gravatar_id":"","url":"https://api.github.com/users/altery","html_url":"https://github.com/altery","followers_url":"https://api.github.com/users/altery/followers","following_url":"https://api.github.com/users/altery/following{/other_user}","gists_url":"https://api.github.com/users/altery/gists{/gist_id}","starred_url":"https://api.github.com/users/altery/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/altery/subscriptions","organizations_url":"https://api.github.com/users/altery/orgs","repos_url":"https://api.github.com/users/altery/repos","events_url":"https://api.github.com/users/altery/events{/privacy}","received_events_url":"https://api.github.com/users/altery/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/spring-projects/spring-boot/labels/in%20progress","name":"in progress","color":"eac04b"}],"state":"closed","locked":false,"assignee":{"login":"dsyer","id":124075,"avatar_url":"https://avatars.githubusercontent.com/u/124075?v=3","gravatar_id":"","url":"https://api.github.com/users/dsyer","html_url":"https://github.com/dsyer","followers_url":"https://api.github.com/users/dsyer/followers","following_url":"https://api.github.com/users/dsyer/following{/other_user}","gists_url":"https://api.github.com/users/dsyer/gists{/gist_id}","starred_url":"https://api.github.com/users/dsyer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dsyer/subscriptions","organizations_url":"https://api.github.com/users/dsyer/orgs","repos_url":"https://api.github.com/users/dsyer/repos","events_url":"https://api.github.com/users/dsyer/events{/privacy}","received_events_url":"https://api.github.com/users/dsyer/received_events","type":"User","site_admin":false},"milestone":null,"comments":2,"created_at":"2015-07-17T14:08:00Z","updated_at":"2015-08-10T10:24:00Z","closed_at":"2015-08-10T10:24:00Z","body":"Relaxed configuration property binding only seems to work for nested properties if the property name is already available, for example in an application.properties.\r\n\r\nFoobarProperties.java\r\n```\r\n@ConfigurationProperties(prefix= \"services.foobar\")\r\n@Component\r\npublic class FoobarProperties {\r\n\r\n\tprivate boolean mock= true;\r\n\r\n\tprivate Nested nested;\r\n\r\n\tpublic boolean isMock () {\r\n\t\treturn this.mock;\r\n\t}\r\n\r\n\tpublic void setMock (boolean mock) {\r\n\t\tthis.mock= mock;\r\n\t}\r\n\r\n\tpublic Nested getNested() {\r\n\t\treturn this.ip2location;\r\n\t}\r\n\r\n\tpublic void setNested(Nested nested) {\r\n\t\tthis.nested= nested;\r\n\t}\r\n\r\n\tpublic static class Nested {\r\n\r\n\t\tprivate String magicValue;\r\n\r\n\t\tpublic String getMagicValue() {\r\n\t\t\treturn this.magicValue;\r\n\t\t}\r\n\r\n\t\tpublic void setMagicValue(String magicValue) {\r\n\t\t\tthis.magicValue= magicValue;\r\n\t\t}\r\n\t}\r\n}\r\n```\r\nDo not configure the properties using a .properties file (application.properties or PropertySource)\r\nInstead, configure the properties by setting the following environment variables:\r\n```\r\nSERVICES_FOOBAR_MOCK=false\r\nSERVICES_FOOBAR_NESTED_MAGICVALUE=42\r\n```\r\nObserve that only the services.foobar.mock is property bound to the configuration class, the services.foobar.nested.magicValue is still undefined (the setter is not called).\r\n\r\nIt seems to work for the non-nested property, because PropertiesConfigurationFactory#getNames() infers complete property names for top-level properties, but not for nested properties.\r\n\r\nNow additionally define the non-working property application.properties (without an actual value):\r\n```\r\nservices.foobar.nested.magicValue=\r\n```\r\n\r\nThe value of 42 is now correctly applied. It seems to work in the this case, because resolution of property values in PropertiesConfigurationFactory#getPropertyValues() honors relaxed binding and applies the value from the 'PropertyValue' instance read from the system environment to the 'PropertyValue' read from the application.properties file, which in turn successfully binds the the configuration bean.\r\n\r\nI found this change, which might be related:\r\nhttps://github.com/spring-projects/spring-boot/pull/2479"}}