Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regression in 4.1.5: Alternative @Bean declarations with same primary bean name do not work anymore [SPR-12744] #17341

Closed
spring-issuemaster opened this issue Feb 23, 2015 · 5 comments

Comments

Projects
None yet
2 participants
@spring-issuemaster
Copy link
Collaborator

commented Feb 23, 2015

Martin Wegner opened SPR-12744 and commented

Since Spring 4.1.5 the DI cannot find my profile activated 'database.dataSource' bean.

My web.xml activates the 'jetty' profile:

<context-param>
  <param-name>spring.profiles.default</param-name>
  <param-value>jetty</param-value>
</context-param>

And my config looks like:

@Profile("live")
@Bean(name = "database.dataSource")
public DataSource jndiDataSource() {
  ...
}
@Profile("!live")
@Bean(name = "database.dataSource")
public DataSource jdbcDataSource() {
  ...
}
@DependsOn({"database.dataSource", "databaseForUnitTestFramework"})
@Bean(name = "sessionFactory")
public LocalSessionFactoryBean localSessionFactoryBean() {
  ...
}

The '!live' annotated bean must be activated and used.
With Spring 4.1.4 and lower it works.
It is a blocker bug because the whole application does not start.


Affects: 4.1.5

Issue Links:

  • #17292 Conditions on an overriding bean method effectively get ignored
  • #19831 Doc: Consistent @Profile declarations on overloaded @Bean methods

Referenced from: commits ce085a6, bb5b5d5

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Feb 23, 2015

Juergen Hoeller commented

I'm pretty sure this is caused by #17292, where the revised algorithm apparently considers your same-named definitions as an override, only evaluating one of them and considering the definition as skipped. My apologies, that's of course an unintended side effect...

The problem originates in the @Bean-specified bean name which is the same for both definitions. Such mutually exclusives profiles should work fine as long you drop that part of the declaration, with the bean name derived from the method name and therefore remaining unique.

I suppose the reason for that explicit name is the @DependsOn expression? Could you potentially drop that depends-on part, expressing the DataSource dependency in a different way, e.g. accepting a DataSource argument in your localSessionFactoryBean method?

That said, we'll fix this for 4.1.6 in any case.

Juergen

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Feb 23, 2015

Juergen Hoeller commented

One more note: You could also declare the bean names using aliases, a la

@Bean(name = {"jndiDataSource, "database.dataSource"})

using a unique primary bean name and an alias to refer to for depends-on declarations. This is probably the most straightforward workaround and hopefully lowers the impact of this issue for the time being.

Juergen

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Feb 23, 2015

Martin Wegner commented

Thank you and until 4.1.6 I will use 4.1.4 :) All my beans have names :) Hm OK, it seems to be a good idea to use an argument instead of a @DependsOn annotation. But I need the @DependsOn annotation for 'databaseForUnitTestFramework' (something must be done before the Hibernate engine starts).

@Profile("live")
@Bean(name = {"jndiDataSource", "database.dataSource"})
public DataSource jndiDataSource() {
  ...
}
@Profile("!live")
@Bean(name = {"jdbcDataSource", "database.dataSource"})
public DataSource jdbcDataSource() {
  ...
}
@DependsOn({"database.dataSource", "databaseForUnitTestFramework"})
@Bean(name = "sessionFactory")
public LocalSessionFactoryBean localSessionFactoryBean() {
  ...
}

What is the advantage of this notation?

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Feb 23, 2015

Juergen Hoeller commented

The advantage of this notation is simply that there are unique bean names to refer to - so at runtime (both within the framework and for live-beans monitoring etc), it's immediately clear which one of the beans has been selected for registration. The fact that you need to talk to them as one 'common' bean is then expressed through the shared alias.

Juergen

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Feb 25, 2015

Juergen Hoeller commented

Fixed through just checking for equivalent method names, not bean names, as it should arguably have been right from the start. Condition overriding with a same-named but overloaded method declaration still works but just specifying the same bean name is not sufficient for a condition override anymore.

Juergen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.