字段存储库需要一个名为“entityManagerFactory”的 bean,但无法找到

Posted

技术标签:

【中文标题】字段存储库需要一个名为“entityManagerFactory”的 bean,但无法找到【英文标题】:Field repository required a bean named 'entityManagerFactory' that could not be found 【发布时间】:2019-02-23 10:02:13 【问题描述】:

我花了几天时间试图解决这个错误,但没有成功。我正在尝试配置两个数据库并写入它们。

我看了:

https://medium.com/@joeclever/using-multiple-datasources-with-spring-boot-and-spring-data-6430b00c02e7

https://www.baeldung.com/spring-data-jpa-multiple-databases

https://www.devglan.com/spring-boot/spring-boot-multiple-database-configuration

https://raymondhlee.wordpress.com/2015/10/31/configuring-multiple-jpa-entity-managers-in-spring-boot/

https://github.com/igormukhin/spring-boot-sample-data-jpa-multiple/blob/master/src/main/java/sample/data/jpa/Database1Configuration.java 并从 SO 中获取更多链接以获取错误或类似示例。

这是我的代码:

fromDB.datasource.url=jdbc:h2:file:D:/test1/db1
fromDB.datasource.username=sa
fromDB.datasource.password=
fromDB.datasource.platform=h2
fromDB.datasource.driverClassName=org.h2.Driver

toDB.datasource.url=jdbc:h2:file:D:/test2/db2
toDB.datasource.username=sa
toDB.datasource.password=
toDB.datasource.platform=h2
toDB.datasource.driverClassName=org.h2.Driver

spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.h2.console.settings.trace=true
spring.h2.console.settings.web-allow-others=true
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

休眠设置-hibernate.properties

spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.use_sql_comments=false
spring.jpa.properties.hibernate.format_sql=true
spring.datasource.initialization-mode=always
spring.datasource.initialize=true
spring.jpa.generate-ddl=true

配置类

    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories(
        entityManagerFactoryRef = "toEntityManager",
        transactionManagerRef = "toTransactionManager",
        basePackages = "leadTime.service"
    )
    public class ToDBConfig 

      @Bean
      @ConfigurationProperties(prefix = "toDB.datasource")
      public DataSource toDataSource() 
        return DataSourceBuilder
            .create()
            .build();
      

      @Bean(name = "toEntityManager")
      public LocalContainerEntityManagerFactoryBean toEntityManagerFactory(
          EntityManagerFactoryBuilder builder) 
        return builder
            .dataSource(toDataSource())
            .properties(hibernateProperties())
            .packages(TestDataTo.class)
            .persistenceUnit("to")
            .build();
      

      @Bean(name = "toTransactionManager")
      public PlatformTransactionManager toTransactionManager(@Qualifier("toEntityManager") EntityManagerFactory entityManagerFactory) 
        return new JpaTransactionManager(entityManagerFactory);
      

      private Map hibernateProperties() 

        Resource resource = new ClassPathResource("hibernate.properties");

        try 
          Properties properties = PropertiesLoaderUtils.loadProperties(resource);

          return properties.entrySet().stream()
              .collect(Collectors.toMap(
                  e -> e.getKey().toString(),
                  e -> e.getValue())
              );
         catch (IOException e) 
          return new HashMap();
        
      
    

第二个配置类

    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories(
        entityManagerFactoryRef = "fromEntityManager",
        transactionManagerRef = "fromTransactionManager",
        basePackages = "leadTime.service"
    )
    public class FromDBConfig 

      @Primary
      @Bean
      @ConfigurationProperties(prefix = "fromDB.datasource")
      public DataSource fromDataSource() 
        return DataSourceBuilder
            .create()
            .build();
      

      @Primary
      @Bean(name = "fromEntityManager")
      public LocalContainerEntityManagerFactoryBean fromEntityManagerFactory(
          EntityManagerFactoryBuilder builder) 
        return builder
            .dataSource(fromDataSource())
            .properties(hibernateProperties())
            .packages(TestDataFrom.class)
            .persistenceUnit("from")
            .build();
      

      @Primary
      @Bean(name = "fromTransactionManager")
      public PlatformTransactionManager fromTransactionManager(@Qualifier("fromEntityManager") EntityManagerFactory entityManagerFactory) 
        return new JpaTransactionManager(entityManagerFactory);
      

      private Map hibernateProperties() 

        Resource resource = new ClassPathResource("hibernate.properties");

        try 
          Properties properties = PropertiesLoaderUtils.loadProperties(resource);

          return properties.entrySet().stream()
              .collect(Collectors.toMap(
                  e -> e.getKey().toString(),
                  e -> e.getValue())
              );
         catch (IOException e) 
          return new HashMap();
        
      

存储库:

    public interface ToRepository extends CrudRepository<TestDataTo, Integer> 
    

      @Override
      TestDataTo save(TestDataTo testDataTo);
    

数据初始化:

    @Component
    public class DataInit 
      @Autowired
      ToRepository toRepository;

      @Autowired
      FromRepository fromRepository;

      @Transactional("fromTransactionManager")
      public void insertDataIntoFromDB() throws SQLException 
        TestDataFrom testDataFrom = new TestDataFrom();
        testDataFrom.setId(1);
        testDataFrom.setName("Test");
        fromRepository.save(testDataFrom);

      
      //
      @Transactional("toTransactionManager")
      public void insertDataIntoToDB() throws SQLException 

        TestDataTo testDataTo = new TestDataTo();
        testDataTo.setId(1);
        testDataTo.setName("Ale");
        toRepository.save(testDataTo);
      
    

主类:

    @EnableTransactionManagement
    @SpringBootApplication
    public class LeadTimeApplication  
      private Logger LOG = LoggerFactory.getLogger("LeadTimeApplication");

      @Autowired
      ToRepository toRepository;

      @Autowired
      FromRepository fromRepository;

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

      

      @Autowired DataInit initializer;

      @PostConstruct
      public void init() throws  SQLException

        initializer.insertDataIntoFromDB();
        initializer.insertDataIntoToDB();

      

错误:

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

Description:

Field toRepository in leadTime.LeadTimeApplication 
required a bean named 'entityManagerFactory' that could not be found.


Action:

Consider defining a bean named 'entityManagerFactory' in your configuration.

我试过了: 使用

@EnableAutoConfiguration(exclude = JpaRepositoriesAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class)

老实说,我不知道还能做什么,我用不同的方法多次重写了这段代码,但都没有成功。如果我让他开始工作,不配置新的 entityManagers 和事务并且不使用@Transactional,应用程序正在工作(创建了 2 个 DB),但两个表都是在同一个 DB 中创建的(当然)

添加 gradle 配置

//Spring dependencies
compile "org.springframework.boot:spring-boot-starter- 
actuator:$springBootVersion"
compile "org.springframework.boot:spring-boot-starter- 
web:$springBootVersion"
compile "org.springframework.boot:spring-boot-starter- 
logging:$springBootVersion"
compile "org.springframework.boot:spring-boot-configuration- 
processor:$springBootVersion"


//JPA dependency
compile "org.springframework.boot:spring-boot-starter-data- 
jpa:$springBootVersion"

testCompile "com.oracle:ojdbc7:12.1.0.2"
testCompile 'com.h2database:h2:1.4.194'
runtime 'com.h2database:h2:1.4.194'
//  compile group: 'h2', name: 'h2', version: '0.2.0'

compile group: 'org.hibernate', name: 'hibernate-entitymanager'
//compile group: 'org.hibernate', name: 'hibernate-gradle-plugin', version: 
'5.3.6.Final'
// https://mvnrepository.com/artifact/org.hibernate/hibernate-core
compile group: 'org.hibernate', name: 'hibernate-core'

【问题讨论】:

很明显你错过了EntityManagerFactory bean 定义。 但是我有两个,每个数据库一个:这应该是其中之一:@Bean(name = "toEntityManager") public LocalContainerEntityManagerFactoryBean toEntityManagerFactory 在example 中,他们使用“entityManagerFactory”作为bean 名称。你可以试试它而不是“toEntityManager”吗? 之前和现在都尝试过:错误-> 不是托管类型:class LeadTime.to.TestDataTo。这几天我试图通过添加EntityScan等来解决它(移动到另一个包中)..但没有成功。 【参考方案1】:

根据你粘贴的内容

https://medium.com/@joeclever/using-multiple-datasources-with-spring-boot-and-spring-data-6430b00c02e7

其中一个 darasource 被配置为“默认”,另一个被命名。您正在创建两个带有 fromto 前缀的“命名”bean。 更改例如from 数据库定义entityManager 而不是fromEntityManager,应该没问题。

我不知道内部原理,但就常识而言,您尝试的应该可行,实际上应用程序配置器需要一些默认数据源,因此会出现错误。

【讨论】:

正如@Boris 建议的那样,我尝试使用“entityManagerFactory”。 IDE 告诉我这是一个默认参数,如果我使用它,我会收到以下错误:不是托管类型:class LeadTime.to.TestDataTo。这几天我试图通过添加EntityScan等来解决它..但没有成功 现在我尝试使用“entityManager”(仅)但我遇到了与以前相同的错误:需要一个名为“entityManagerFactory”的bean,但无法找到。 @Agata - 你的问题解决了吗?我也一样:( @Matley,检查此链接并将类放在不同的包中(这是我的 porb):github.com/spring-projects/spring-data-examples/tree/master/jpa/…

以上是关于字段存储库需要一个名为“entityManagerFactory”的 bean,但无法找到的主要内容,如果未能解决你的问题,请参考以下文章

如何在内存数据库中使用 H2 测试 EntityManager 查询

在 Spring 存储库中注入 EntityManager 时出现 java.lang.NullPointerException

JPA 数据存储库 - 找到 2 个 EntityManager 类型的 bean

JPA 和 Play 框架:EntityManager 没有名为更新的持久性提供程序

entitymanagerupdate数据未更新null

只读数据库视图如何适应存储库模式?