Skip to content

Validation not working when nested records are used for configuration properties #39234

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

Closed
michalgebauer opened this issue Jan 18, 2024 · 4 comments
Labels
status: invalid An issue that we don't feel is valid

Comments

@michalgebauer
Copy link

michalgebauer commented Jan 18, 2024

I tried both ways how to use nested records as configuration properties. In non of them validation works. I have in the same project configuration with just one record without nesting and that works.

Examples

@Validated
@ConfigurationProperties(prefix = "client")
public record ClientProperties(@NestedConfigurationProperty ServiceOne serviceOne) {
}

@Validated
record ServiceOne(@NotBlank String url, @Email String email) {
}
@Validated
@ConfigurationProperties(prefix = "client")
public record ClientProperties(ServiceOne serviceOne) {

    @Validated
    public record ServiceOne(@NotBlank String url, @Email String email) {
    }

}
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jan 18, 2024
@wilkinsona
Copy link
Member

Thanks for the report. Unfortunately, it doesn't provide enough information for us to diagnose the problem. We need to know the version of Spring Boot that you're using as well as the client.service-one.* properties that you're trying to bind. The properties are important as, depending on what they are, a ServiceOne instance may not even be created. Please provide this information to us in the form of a complete yet minimal sample that reproduces the problem you have described. You can share it with us by pushing it to a separate repository on GitHub or by zipping it up and attaching it to this issue.

@wilkinsona wilkinsona added the status: waiting-for-feedback We need additional information before we can continue label Jan 18, 2024
@michalgebauer
Copy link
Author

I'm using Spring Boot 3.2.1, all properties are actually null (not provided).
See my demo project I created just for the purpose of this issue:
https://github.com/michalgebauer/nested-records-validation/blob/main/src/main/java/com/example/demo/DemoApplication.java

I have similar problems with nested properties even if I use classes and not records.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Jan 18, 2024
@wilkinsona
Copy link
Member

wilkinsona commented Jan 18, 2024

Thanks. The behaviour you have described is to be expected. With no properties to bind to an instance of ServiceOne, no instance of it is created and, therefore, there's nothing to validate. If you want to prohibit this, you can annotate the record component with @NotNull:

@Validated
@ConfigurationProperties(prefix = "client")
record ClientProperties(@NotNull ServiceOne serviceOne) {

	public record ServiceOne(@NotBlank String url, @Email String email) {
	}

}

With this in place, the app will fail to start due to a validation failure:

Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'client' to com.example.demo.ClientProperties failed:

    Property: client.serviceOne
    Value: "null"
    Reason: must not be null

Alternatively, you can annotate it with both @Valid and @DefaultValue:

@Validated
@ConfigurationProperties(prefix = "client")
record ClientProperties(@DefaultValue @Valid ServiceOne serviceOne) {

	public record ServiceOne(@NotBlank String url, @Email String email) {
	}

}

This will cause the binder to create a default ServiceOne instance with null url and email components. It too will fail validation when the app starts but with an arguably better error message:

Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'client' to com.example.demo.ClientProperties failed:

    Property: client.serviceOne.url
    Value: "null"
    Reason: must not be blank

@wilkinsona wilkinsona added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels Jan 18, 2024
@wilkinsona wilkinsona closed this as not planned Won't fix, can't repro, duplicate, stale Jan 18, 2024
@wilkinsona wilkinsona added status: invalid An issue that we don't feel is valid and removed status: waiting-for-feedback We need additional information before we can continue status: waiting-for-triage An issue we've not yet triaged labels Jan 18, 2024
@michalgebauer
Copy link
Author

Thank you 🙌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests

3 participants