The application.properties

customer.metadata.intKey=123
customer.metadata.booleanKey=true

The CustomerProperties.java

@ConfigurationProperties(prefix = "customer")
public class CustomerProperties {
    private Map<String, Object> metadata;

    public Map<String, Object> getMetadata() {
        return metadata;
    }

    public void setMetadata(Map<String, Object> metadata) {
        this.metadata = metadata;
    }
}

The Application.java

@SpringBootApplication
@EnableConfigurationProperties(CustomerProperties.class)
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public ApplicationRunner runner(CustomerProperties customerProperties) {
        return args -> {
            // Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
            Integer value = (Integer) customerProperties.getMetadata().get("intKey");
            System.out.println(value);
        };
    }
}

The Error stack

java.lang.IllegalStateException: Failed to execute ApplicationRunner
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:778) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
    at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:765) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:322) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
    at com.yuhb.gateway.Application.main(Application.java:17) [classes/:na]
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
    at com.yuhb.gateway.Application.lambda$runner$0(Application.java:23) [classes/:na]
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:775) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
    ... 5 common frames omitted

Comment From: wilkinsona

There's no type information to lose as there's no type information in a properties file – the keys and values are all strings. Your metadata map doesn't constrain the type of its values (it's using Object) so there's no way of knowing what type you want them to have. As a result, the values are left as strings.

If the map constrained the type, for example by being a Map<String, Integer>, each value would be converted to an Integer automatically. As you are mixing types this won't help in this specific case. Instead, you may want to consider replacing the map with a rich type with intKey and booleanKey properties that are typed as int and boolean respectively.

If you have any further questions, please follow up on Stack Overflow or Gitter. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.