Spring Boot #ConfigurationProperties for nested structure - spring

I have a configuration similar to below
spring:
source:
prop1: ['abc', 'def']
prop2: some-value
destination:
prop1: some-other-value
I am trying to read the above configuration with the below Classes
#Configuration
#ConfigurationProperties(prefix = "spring")
#Getter
#Setter
public class ClientConfiguration {
private Source source;
private Destination destination;
}
#Getter
#Setter
#AllArgsConstructor
#Configuration
#ConfigurationProperties(prefix = "source")
public class Source {
private List<String> prop1;
private String prop2;
}
#AllArgsConstructor
#Getter
#Setter
#Configuration
#ConfigurationProperties(prefix = "destination")
public class Destination {
private String prop1;
}
However, I am getting an error with this setup.
Could not bind properties to ClientConfiguration (prefix=spring, ignoreInvalidFields=false, ignoreUnknownFields=true, ignoreNestedProperties=false); nested exception is org.springframework.beans.NullValueInNestedPathException: Invalid property 'source' of bean class [ClientConfiguration$$EnhancerBySpringCGLIB$$f1eacf3e]: Could not instantiate property type [Source] to auto-grow nested property path; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [Source]: Is it an abstract class?; nested exception is java.lang.InstantiationException: Source
Please let me know how to parse the nested configuration using nested objects.

Related

It is not possible to automatically connect the bean from the user library.(Spring)

I use spring-boot (2.6.7).
the custom library is downloaded from private nexus repository and I see in classpath of project.
I have a custom library and I want to configure the bean. so that another component in the project automatically implements it to itself already configured.
bean from library
//library
public interface Helper<S,T> {
T prepare(S messageMetaDto);
}
implementation that bean in the library
//library
#RequiredArgsConstructor
public class HelperImpl
implements Helper<MessageMetaDto, EmailDto<MessageDto>> {
private final MessageConverter<InfoDto, MessageDto> messageConverter;
#Override
public EmailDto<MessageDto> prepare(MessageMetaDto messageMetaDto) {
....
}
}
//library
#Data
#Builder
#AllArgsConstructor
public class EmailDto<T> {
private T message;
#NotBlank
private String name;
}
in myProject
#Configuration
public class TemplateConfig {
#Bean(name = "prepareMessage")
public Helper<MessageMetaDto, EmailDto<MessageDto>> prepareMessage(MessageConverter<InfoDto, MessageDto> messageConverter){
return new HelperImpl(messageConverter);
}
#Bean
public MessageConverter<InfoDto, AzureMessageDto> messageConverter(){
return new MessageConverterImpl();
}
}
the bean Helper - > not found
but the bean MessageConverter - has created.
Why a bean with nested parameters is not created, but another one is created.
But after all, the integration tests when I ran them in the library were in order, such a complex generic did not affect ?
What could be the problem ?
there was a duplicate data model
//library
#Data
#Builder
#AllArgsConstructor
public class EmailDto<T> {
private T message;
#NotBlank
private String name;
}
in the project . I removed it from the project, then the component from the library was normally initialized and added to the Application context.

use spring-data-r2dbc, Unable to inject DAO interface,Field myDao in ServiceImpl required a bean of type 'UmsAddressDao' that could not be found

1.illustrate
springboot 2.3.7
springboot-data-r2dbc 1.1.6
2.I used Spring-Data-R2DBC to operate mysql, but I have been reporting an errororg.springframework.beans.factory.UnsatisfiedDependencyException
3.Complete error description
cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webFluxController': Unsatisfied dependency expressed through field 'umsAddressService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'umsAddressServiceImpl': Unsatisfied dependency expressed through field 'umsAddressDao'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.xxx.inner.UmsAddressDao' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Field umsAddressDao in com.xxx.impl.UmsAddressServiceImpl required a bean of type 'com.xxx.inner.UmsAddressDao' that could not be found.
3.My code snippet
my controller
#RestController
public class WebFluxController {
private Logger log = LoggerFactory.getLogger(WebFluxController.class);
#Autowired
private UmsAddressService umsAddressService;
#Autowired
private StringRedisTemplate stringRedisTemplate;
#Autowired
private QuestionService questionService;
// do something
}
my service
public interface UmsAddressService {
Mono<UmsAddress> findById(Long id);
}
my service impl
#Service
public class UmsAddressServiceImpl implements UmsAddressService {
#Autowired
private UmsAddressDao umsAddressDao;
#Override
public Mono<UmsAddress> findById(Long id) {
return umsAddressDao.findById(id);
}
}
my dao
#Component
public interface UmsAddressDao extends ReactiveCrudRepository<UmsAddress,Long> {
}
my model
#Data
#Accessors(chain = true)
#ToString
#Table("ums_address")
public class UmsAddress {
#Id
#Column("id")
private Long id;
#Column("member_id")
private Long memberId;
// other field
}
springbootApplication
#EnableWebFlux
#SpringBootApplication( exclude = { RedisRepositoriesAutoConfiguration.class })
#OpenAPIDefinition(info = #Info(title = "APIs", version = "1.0", description = "Documentation APIs v1.0"))
public class MyWebApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(RollkingWebApplication.class).web(WebApplicationType.REACTIVE).run(args);
}
}

No qualifying bean, annotated with #ConfigurationProperties

I use #ConfigurationProperties for configurating properties:
#Getter
#Setter
#ConfigurationProperties("kafka")
public class KafkaConnectionSettings {
private String bootstrapAddress = "dataflow-kafka:9092";
{
And trying to autowire it in other configuration-class. For example:
#Configuration
#AllArgsConstructor
public class KafkaProducerConfig {
private KafkaConnectionSettings kafkaSettings;
#Bean
public ProducerFactory<String, String> producerFactory() {
Map<String, Object> configProps = new HashMap<>();
configProps.put(
ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,kafkaSettings.getBootstrapAddress());
}
}
But I receive the following exeption:
No qualifying bean of type 'com.app.config.kafka.KafkaConnectionSettings' available: expected single matching bean but found 2: kafkaConnectionSettings,kafka-com.app.config.kafka.KafkaConnectionSettings
Its a "little" strange, considering that in "com.app.config"-package I have a similar config:
#Getter
#Setter
#ConfigurationProperties("app")
public class FileSettings {
}
and this last authowired successfully in classes, annotated with #Service
What am I doing wrong?
The problem is solved. I forgot to add KafkaConnectionSettings.class in #EnableConfigurationProperties at my testclass
#ActiveProfiles("test")
#EnableConfigurationProperties({FileSettings.class, KafkaConnectionSettings.class})
#RunWith(SpringRunner.class)
#SpringBootTest
public class AppTest {
Sorry for not quite clear question.

Annotation Value is not working in spring boot

I want to read few values from properties file through #Value annotation, but getting error.
Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'rcm.datasource.driverClassName' in value "${rcm.datasource.driverClassName}"
properties file
rcm.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
java class
#Configuration
public class RcmDBConfig {
#Value("${rcm.datasource.driverClassName}")
private String driverClassName;
#Bean(name = "rcmEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean productEntityManager() {
LocalContainerEntityManagerFactoryBean em
= new LocalContainerEntityManagerFactoryBean();
System.out.println(driverClassName);
}
}
The value can be able to inject if you have specified the component-scan package properly; otherwise spring boot can't be able to detect the packages for auto-configuration.
Ex:
#Configuration
#EnableAutoConfiguration
#ComponentScan({"com.deb.xyz.*"})
#SpringBootApplication
public class Application{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
and your RcmDBConfig.java must be in package like com.deb.xyz.config
you can use like this
#Configuration
public class MyDatabaseConfig {
#Bean(name = "myDataSource")
#Primary
#ConfigurationProperties(prefix = "spring.datasource")
public DataSource myDataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
here is the yml file
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: ****
password: ***********
jdbc-url : jdbc:mysql://localhost:3306/myshema?autoReconnect=true&autoReconnectForPools=true&zeroDateTimeBehavior=convertToNull&serverTimezone=UTC
or you just want to read yml or properties files in java class
the like this
#Component
#ConfigurationProperties("spring.datasource")
#Getter
#Setter
public class SpringYMLData {
private String driver-class-name;
private String username;
private String password;
private String jdbc-url;
}

MongoDB and Spring JPA integration is throwing error

I am trying to integrate Spring JPA with MongoDB. My intention is to just retrieve data from mongo DB. I am getting the below error while injecting my repository.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.org.coop.society.data.mongo.repositories.MaterialMasterRepository com.org.coop.security.service.MongoService.materialMasterRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'materialMasterRepository': Invocation of init method failed; nested exception is java.lang.AbstractMethodError
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
My configuration snippet is given below.
TestMongoDBConfig.java
#Configuration
#EnableMongoRepositories(basePackages = {"com.abc.data.mongo.repositories"})
#ComponentScan(basePackages = "com.abc")
#PropertySource("classpath:applicationTest.properties")
public class TestMongoDBConfig extends AbstractMongoConfiguration {
#Autowired
private Environment env;
#Override
protected String getDatabaseName() {
return "retail";
}
#Override
#Bean
public MongoClient mongo() throws Exception {
MongoClient client = new MongoClient("localhost", 27017);
return client;
}
#Override
protected String getMappingBasePackage() {
return "com.abc.data.mongo.entities";
}
#Bean
public MongoTemplate mongoTemplate() throws Exception {
return new MongoTemplate(mongo(), getDatabaseName());
}
}
MaterialMaster.java in com.abc.data.mongo.entities package
#Document(collection = "materialMaster")
public class MaterialMaster {
#Id
private Long materialId;
#Field
private String name;
MaterialMasterRepository.java in com.abc.data.mongo.repositories package
public interface MaterialMasterRepository extends MongoRepository<MaterialMaster, Long> {
}
MongoService.java in com.abc.service package
#Service
public class MongoService {
#Autowired
private MaterialMasterRepository materialMasterRepository;
public void getMaterials() {
List<MaterialMaster> materials = materialMasterRepository.findAll();
System.out.println(materials);
}
}
Junit class looks like below
#RunWith(SpringJUnit4ClassRunner.class)
#ComponentScan(basePackages = "com.abc")
#ContextHierarchy({
#ContextConfiguration(classes={TestMongoDBConfig.class})
})
public class ModuleWSTest {
#Autowired
private MongoService mongoService;
#Test
public void testModule() {
mongoService.getMaterials();
}
}
I have tried all possible changes (as per my knowledge) but no luck. Any help is really appreciated.
The error message is little confusing. I was using latest spring-data-mongodb (1.8.4.RELEASE). Once I downgraded the dependency to 1.6.0.RELEASE then the above configuration started working.

Resources