0

I have the following issue. I create a data source based on a value I read in the yaml file based on a given profile.

Here is my code

@Value("${my.db.serviceId}")
private String serviceId;

@Primary
@Bean(name = "prodDataSource")
@Profile("prod")
public DataSource prodDataSource() {
    return getDataSource(serviceId);
}

@Bean(name = "devDataSource")
@Profile("dev")
public DataSource devDataSource() {
    return getDataSource(serviceId);
}

Here is my yaml file

---

spring:
   profile: dev
my:
  db:
    serviceId: 'my-dev-service'
---

spring:
  profile: prod
my:
 db:
   serviceId: 'my-prod-service'

---

My current issue is that when I start my application with the "dev" profile, the value of the serviceId is 'my-prod-service'.

What am I doing wrong here?

The Reedemed77
  • 419
  • 1
  • 6
  • 14

2 Answers2

1

@Primary annotation enables a bean that gets preference when more than one bean is qualified to autowire a single valued dependency

So the bean with @Primary annotation will get more preference

Ryuzaki L
  • 37,302
  • 12
  • 68
  • 98
  • I don't think so, `@Bean(name = "prodDataSource")` and `@Bean(name = "devDataSource")` are different beans. – Vy Do Aug 17 '18 at 16:15
  • ` Suppose we have a super class or interface and it has some sub classes and all the subclasses are bean. Now in a class we have a setter method or property which is autowired for super class. In this case all the sub classes are eligible for dependency injection. And hence spring container will throw error because it is unable to select a bean for dependency injection because of more than one eligible candidate. In this case we can give preference to a bean using @Primary annotation on one sub class. Now this bean will be selected for the dependency injection.` – Ryuzaki L Aug 17 '18 at 16:17
  • So thinking more about it, since the value of the service really determines the datasource I thought it would make sense to have only datasource bean. and remove the profile annotation. So then the profile would be determine by the value passed when starting the application. but I still get the same result. – The Reedemed77 Aug 17 '18 at 16:30
  • then it's not picking up your profile, how are you specifying profile? `spring.profiles.active=dev` like this – Ryuzaki L Aug 17 '18 at 16:34
  • That's quite odd. I'm using the following -Dspring.profiles.active=dev. but it's quite odd that is not picking up my profile. How can I make it pick the profile. – The Reedemed77 Aug 17 '18 at 16:40
  • can you try this `java -jar myproject.jar --spring.profiles.active=test` or you are running this in eclipse? – Ryuzaki L Aug 17 '18 at 16:41
  • I'm running in intelliJ – The Reedemed77 Aug 17 '18 at 16:43
  • there are multiple ways but try this, add this to env variables in run config `spring.profiles.active=dev` this should work – Ryuzaki L Aug 17 '18 at 16:47
  • did it worked? check this for more clarity https://stackoverflow.com/questions/31038250/setting-active-profile-and-config-location-from-command-line-in-spring-boot – Ryuzaki L Aug 17 '18 at 16:56
  • it should work or `--spring.profiles.active=dev` pass like this in program arguments , it should work i don't know what wrong thing you are doing – Ryuzaki L Aug 17 '18 at 18:16
  • So in my yml file I rename the field to myBbServiceId: 'my-dev-service' and it worked. – The Reedemed77 Aug 17 '18 at 18:29
0

so I finally realized that in the yaml file I put "profile" instead of "profiles". that's why it wasn't picking up my profile.

I endeded up changing to:

---

spring:
   profiles: dev
my:
 db:
  serviceId: 'my-dev-service'
---

spring:
   profiles: prod
my:
 db:
  serviceId: 'my-prod-service'

---
The Reedemed77
  • 419
  • 1
  • 6
  • 14