I am using spring boot 1.5.9 to write a small rest server. I have just started of with initialization code and got stuck with this weird behavior.
I have a small test -
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestMongo {
@Autowired
private MongoOperations mongoOps;
@Test
public void testMongoConnection() {
assertFalse(mongoOps.collectionExists("test"));
}
}
Initially, the application.properties were being ignored. After I added the @SpringBootTest annotation, the application.properties were read but the following error started occurring.
Caused by: org.springframework.validation.BindException: org.springframework.boot.bind.RelaxedDataBinder$RelaxedBeanPropertyBindingResult: 1 errors Field error in object 'mongo' on field 'port': rejected value [${mongo.port:27017}]; codes [typeMismatch.mongo.port,typeMismatch.port,typeMismatch.int,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [mongo.port,port]; arguments []; default message [port]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'int' for property 'port'; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [int]] at org.springframework.boot.bind.PropertiesConfigurationFactory.checkForBindingErrors(PropertiesConfigurationFactory.java:359) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE] at org.springframework.boot.bind.PropertiesConfigurationFactory.doBindPropertiesToTarget(PropertiesConfigurationFactory.java:276) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE] at org.springframework.boot.bind.PropertiesConfigurationFactory.bindPropertiesToTarget(PropertiesConfigurationFactory.java:240) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE] at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization(ConfigurationPropertiesBindingPostProcessor.java:330) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE] ... 56 common frames omitted
I have tried this declaring port as java.lang.Integer as well as int.
The configuration beans look like this -
@Configuration
@EnableConfigurationProperties(MongoProperties.class)
public class SpringConfiguration {
private MongoProperties mongoPropertiesConfiguration;
public MongoProperties getMongoConfiguration() {
return mongoPropertiesConfiguration;
}
@Autowired
public void setMongoConfiguration(MongoProperties mongoConfiguration) {
this.mongoPropertiesConfiguration = mongoConfiguration;
}
public @Bean MongoClient mongoClient() {
return new MongoClient(mongoPropertiesConfiguration.getHost(), mongoPropertiesConfiguration.getPort());
}
public @Bean MongoDbFactory mongoDbFactory() {
return new SimpleMongoDbFactory(mongoClient(), mongoPropertiesConfiguration.getDb());
}
public @Bean MongoOperations mongoOperations() {
return new MongoTemplate(mongoDbFactory());
}
}
And
@ConfigurationProperties(prefix="mongo")
public class MongoProperties {
private String host;
private Integer port;
private String db;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public Integer getPort() {
return port;
}
public void setPort(Integer port) {
this.port = port;
}
public String getDb() {
return db;
}
public void setDb(String db) {
this.db = db;
}
}
I did get the test running with @EnableAutoConfiguration annotation instead of @SpringBootTest. But that worked just for one of the tests. I think it matters in which package your test is and I think that @EnableAutoConfiguration may not be the right approach.
I have been debugging the spring source for some time now, without any leads.
Please let me know if you have any suggestions.
EDIT 1: As requested, adding the application.properties
mongo.host=localhost
mongo.port=${mongo.port:27017}
mongo.db=${mongo.db:synctool}