Spring-boot: @ConditionalOn repositories fails on 2.0.0.M2 and snapshot

Created on 23 Jun 2017  路  9Comments  路  Source: spring-projects/spring-boot

Marking a spring data repository with @ConditionalOnProperty (or others) causes application to fail to start with exception:

Caused by: java.lang.IllegalStateException: No ConfigurableListableBeanFactory available
    at org.springframework.util.Assert.state(Assert.java:73) ~[spring-core-5.0.0.RC2.jar:5.0.0.RC2]
    at org.springframework.context.annotation.ConditionEvaluator$ConditionContextImpl.getBeanFactory(ConditionEvaluator.java:205) ~[spring-context-5.0.0.RC2.jar:5.0.0.RC2]
    at org.springframework.boot.autoconfigure.condition.SpringBootCondition.recordEvaluation(SpringBootCondition.java:113) ~[spring-boot-autoconfigure-2.0.0.M2.jar:2.0.0.M2]
    at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:49) ~[spring-boot-autoconfigure-2.0.0.M2.jar:2.0.0.M2]
    ... 40 common frames omitted

To reproduce just need to add @ConditionalOn on a repository as in:

@ConditionalOnProperty("xpto")
public interface XptoRepository extends CrudRepository<Xpto,Integer> {}

This used to work on 1.5.*

regression

All 9 comments

@manuel-sousa I suspect there's more to this. The failure would suggest that you've customised the bean factory and it isn't a ConfigurableListableBeanFactory. Can you please provide a sample that reproduces the problem?

I can reproduce the issue. If I revert, for the sake of the demo, to Kay.M3 the error goes away.

@snicoll I'm not sure if this is a regression in Boot. It looks like this might have caused it?

This is really weird. It doesn't fail with Kay-M3 because Spring Data's RepositoryComponentProvider scans org.springframework.boot.autoconfigure.data.jpa rather than com.example.demo. As a result, the repository is never created with or without the condition on it. So it doesn't fail but it's not really working either.

It works properly in 1.5.x, but the condition evaluation isn't reported as the BeanFactory in the condition context is null. That points to the change that @mbhave linked to above. I can't see any reason for the BeanFactory in the context being null as there's a DefaultListableBeanFactory in the call stack at the time of the condition evaluation.

I think it's null because RepositoryComponentProvider doesn't override getRegistry and the ClassPathScanningCandidateComponentProvider always returns null (if that ever gets called).

Ah, yes. That's exactly the reason. Thank you, @mbhave. I guess we should raise a Spring Data Commons issue to see if they can change that. I'm also not sure about the Spring Framework change. It seems rather odd to allow the condition context to be created with a null registry, or one from which a bean factory cannot be obtained, and yet throw an exception from getBeanFactory(). I think @Nullable on getBeanFactory() might be better.

Thank you for the sample, @manuel-sousa.

I've opened SPR-15698 and DATACMNS-1098. If neither of those comes to fruition then I guess we'll have to catch the IllegalStateException.

With thanks to @olivergierke, some changes have been made in Spring Data Commons. I've just adapted Spring Boot to those changes so this should now be fixed.

Was this page helpful?
0 / 5 - 0 ratings