Consider an auto-configuration class that has @AutoConfigureBefore(HibernateJpaAutoConfiguration.class) and registers a custom EntityManagerFactoryDependsOnPostProcessor using @Import.

My custom EntityManagerFactoryDependsOnPostProcessor is not created or used.

Sample repo: https://github.com/cdalexndr/spring-issue-29018

Spring Boot 2.6.1

Comment From: philwebb

I think this might be a limitation of the @Configuration class parsing code in Spring Framework. If you remove the @Import line and add the following static method the things appear to work:

    @Bean
    @ConditionalOnClass(LocalContainerEntityManagerFactoryBean.class)
    @ConditionalOnBean(AbstractEntityManagerFactoryBean.class)
    public static MyCustomBeanEntityManagerFactoryDependsOnPostProcessor myCustomBeanEntityManagerFactoryDependsOnPostProcessor() {
        return new MyCustomBeanEntityManagerFactoryDependsOnPostProcessor();
    }

I'll transfer this issue to the Spring Framework team to see if the limitation is intentional or not.

Comment From: cdalexndr

Note the same technique with @Import(BeanFactoryPostProcessor) is used in Spring Boot's CacheAutoConfiguration. The difference in my code is that I use @AutoConfigureBefore that seems to cause the issue.

Comment From: philwebb

Thanks @cdalexndr, I missed that detail. I guess this one is a Spring Boot issue after all.

Comment From: philwebb

@cdalexndr I think I know what's going on here and why CacheAutoConfiguration works but yours does not. You have @ConditionalOnBean(AbstractEntityManagerFactoryBean.class) declared on MyCustomBeanEntityManagerFactoryDependsOnPostProcessor but nothing has defined that bean when MyConfiguration imports MyCustomBeanEntityManagerFactoryDependsOnPostProcessor.

The @ConditionalOnBean only works against bean definitions that have already been defined. This means that the auto-configuration that defines AbstractEntityManagerFactoryBean must run before your configuration. With CacheAutoConfiguration we have a @AutoConfigureAfter for HibernateJpaAutoConfiguration. With your example code you have @AutoConfigureBefore(HibernateJpaAutoConfiguration.class). So the order for your code is:

  • MyConfiguration beans are defined
  • MyCustomBeanEntityManagerFactoryDependsOnPostProcessor is imported
  • @ConditionalOnBean(AbstractEntityManagerFactoryBean.class) doesn't match because no AbstractEntityManagerFactoryBean has been defined

I think you'll need to rethink your @AutoConfigureBefore/@AutoConfigureAfter annotations.