需要一个类型为 'org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder' 的bean,但找不到。

8
我有一个连接到2个不同数据源的Spring Boot 2.4.0应用程序,我一直收到这个错误。我在互联网上搜索了解决方案,发现需要使用@Primary指定其中一个bean,但我已经这样做了(所以这不是我的问题)。下面是错误和类的代码,请帮忙解决,谢谢: 错误:
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.> 
<Jun 14, 2021 11:07:01 AM EEST> <Notice> <Stdout> <BEA-000000> <2021-06-14 11:07:01.740 ERROR 7845 --- [ (self-tuning)'] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of method entityManagerFactory in demo.Db1Config required a bean of type 'org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder' that could not be found.


Action:

Consider defining a bean of type 'org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder' in your configuration.> 
<Jun 14, 2021 11:07:01 AM EEST> <Error> <Deployer> <BEA-149265> <Failure occurred in the execution of deployment request with ID "430590093957351" for task "888" on [partition-name: DOMAIN]. Error is: "weblogic.application.ModuleException: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}"
weblogic.application.ModuleException: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
    at weblogic.application.internal.ExtensibleModuleWrapper.start(ExtensibleModuleWrapper.java:140)
    at weblogic.application.internal.flow.ModuleListenerInvoker.start(ModuleListenerInvoker.java:124)
    at weblogic.application.internal.flow.ModuleStateDriver$3.next(ModuleStateDriver.java:237)
    at weblogic.application.internal.flow.ModuleStateDriver$3.next(ModuleStateDriver.java:232)
    at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:45)
    Truncated. see log file for complete stacktrace
Caused By: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1777)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1333)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1287)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:885)
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:789)
    Truncated. see log file for complete stacktrace

Db1Config.java:

@Configuration
@EnableTransactionManagement
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
@EnableJpaRepositories(entityManagerFactoryRef = "db1EntityManagerFactory",
        basePackages = {"demo.db1.repo"})
public class Db1Config {

    @Primary
    @Bean(name = "db1DataSource", destroyMethod="")
    @ConfigurationProperties(prefix = "db1.datasource")
    public DataSource dataSource() {
        JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
        DataSource dataSource = dataSourceLookup.getDataSource("jdbc/JNDI_NAME_1");
        return dataSource;
    }

    @Primary
    @Bean(name = "db1EntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(
            EntityManagerFactoryBuilder builder, @Qualifier("db1DataSource") DataSource dataSource) {
        return builder.dataSource(dataSource).packages("demo.db1.domain").persistenceUnit("db1")
                .build();
    }

    @Primary
    @Bean(name = "db1TransactionManager")
    public PlatformTransactionManager transactionManager(
            @Qualifier("db1EntityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

Db2Config.java:

@Configuration
@EnableTransactionManagement
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
@EnableJpaRepositories(entityManagerFactoryRef = "db2EntityManagerFactory",
        transactionManagerRef = "db2TransactionManager", basePackages = {"demo.db2.repo"})
public class Db2Config {

    @Bean(name = "db2DataSource", destroyMethod="")
    @ConfigurationProperties(prefix = "db2.datasource")
    public DataSource dataSource() {
        JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
        DataSource dataSource = dataSourceLookup.getDataSource("jdbc/JNDI_NAME_2");
        return dataSource;
    }

    @Bean(name = "db2EntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean barEntityManagerFactory(
            EntityManagerFactoryBuilder builder, @Qualifier("db2DataSource") DataSource dataSource) {
        return builder.dataSource(dataSource).packages("demo.db2.domain").persistenceUnit("db2")
                .build();
    }

    @Bean(name = "db2TransactionManager")
    public PlatformTransactionManager barTransactionManager(
            @Qualifier("db2EntityManagerFactory") EntityManagerFactory barEntityManagerFactory) {
        return new JpaTransactionManager(barEntityManagerFactory);
    }
}

Application.java:

@SpringBootApplication(exclude = HibernateJpaAutoConfiguration.class)
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

ServletInitializer.java:

public class ServletInitializer extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

    @Bean
    public MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        factory.setMaxFileSize(DataSize.ofMegabytes(100000L));
        factory.setMaxRequestSize(DataSize.ofMegabytes(100000L));
        return factory.createMultipartConfig();
    }
}


乍一看,我看不出你的代码有什么问题。但通常这种错误发生在Spring没有扫描所有涉及的包,因此找不到bean时会发生。你确定 Db1Config 被正确地拾取了吗?你可以尝试使用 @Import 手动导入它。或者可能有另一个异常出现在更早的阶段,阻止了你的 EntityManagerFactory Bean 的实例化。 - geanakuch
我注意到,如果我从Db1Config.java或Db2Config.java中删除注释@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}),则此行中的单词builder:EntityManagerFactoryBuilder builder,@Qualifier("db1DataSource") DataSource dataSource)会出现红色下划线,并显示“无法自动装配。找不到类型为EntityManagerFactoryBuilder的bean”,即使Maven生命周期运行没有错误。 - Marius Pop
@MariusPop 这个部署成了一个 war 文件并运行在 Weblogic 服务器上了吗? - Panagiotis Bougioukos
是的,它已部署在正在运行的Weblogic服务器上。 - Marius Pop
1个回答

13

我看到在Application.java中存在问题,因为你已经排除了HibernateJpaAutoConfiguration.class,而该自动配置器与JpaBaseConfiguration类有关,在该类中EntityManagerFactoryBuilder被创建。 enter image description here 之后你有两个解决问题的选项:

  • 删除排除,并逐步解决使用两个DataSource的其他问题
  • 您可以手动创建EntityManagerFactoryBuilder,如屏幕截图或以下代码片段所示:
@Bean
public EntityManagerFactoryBuilder entityManagerFactoryBuilder() {
   return new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter(), new HashMap<>(), null);
}

提示:我不确定您需要在配置文件中完全包含以下代码:

@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接