1

I am trying to write a micronaut function which is deploying as AWS Lambda.

With my micronaut function, I need to connect to multiple databases and get the data and put details into AWS SQS. In this regard, I am trying to use JDBC template approach to get data from different data sources. But I am getting error: Multiple possible bean candidates found: [org.springframework.jdbc.core.JdbcTemplate, org.springframework.jdbc.core.JdbcTemplate, org.springframework.jdbc.core.JdbcTemplate] error

package io.test.invoice;

import io.micronaut.context.annotation.Factory;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.inject.Named;
import javax.inject.Singleton;
import javax.sql.DataSource;

@Factory
public class JdbcTemplateFactory {

    @Singleton
    JdbcTemplate jdbcTemplateOne(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

    @Singleton
    JdbcTemplate jdbcTemplateTwo(@Named(value = "database2") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
}
package io.test.invoice;

import io.micronaut.context.annotation.Requires;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.inject.Singleton;
import java.util.List;

@Singleton
@Requires(beans = JdbcTemplate.class)
public class CodeSetRepository {
    private final JdbcTemplate jdbcTemplateOne;
    private final JdbcTemplate jdbcTemplateTwo;

    public CodeSetRepository(JdbcTemplate jdbcTemplateOne, JdbcTemplate jdbcTemplateTwo) {
        this.jdbcTemplateOne = jdbcTemplateOne;
        this.jdbcTemplateTwo = jdbcTemplateTwo;
    }

    public List<CodeSet> getAllCodeSets() {
        String SELECT_QUERY = "SELECT * FROM public.code_set";
        return this.jdbcTemplateTwo.query(SELECT_QUERY, new BeanPropertyRowMapper(CodeSet.class));
    }

    public List<Country> getAllCountries() {
        String SELECT_QUERY = "SELECT * FROM public.country";
        return this.jdbcTemplateOne.query(SELECT_QUERY, new BeanPropertyRowMapper(Country.class));
    }
}

Could anyone help with this please?

Buddha
  • 185
  • 1
  • 15

2 Answers2

0

The name of the parameter jdbcTemplateOne has no bearing on the injection. So both parameters are asking for the same thing. There are multiple templates thus Micronaut doesn't know which one to inject.

In your factory you can create a template for each datasource with

@EachBean(DataSource.class)
JdbcTemplate jdbcTemplateOne(DataSource dataSource) {
    return new JdbcTemplate(dataSource);
}

Then the named qualifier of the datasource will transfer to the template. That means in your example you could inject @Named("database2") JdbcTemplate jdbcTemplate.

Alternatively you can add @Named qualifiers to the factory methods and then inject the jdbc templates with those qualifiers.

James Kleeh
  • 12,094
  • 5
  • 34
  • 61
0

Change your repository constructor like below

   @Inject
   public CodeSetRepository(@Named("database2") JdbcTemplate jdbcTemplateOne) {
        this.jdbcTemplateOne = jdbcTemplateOne;
   }