1

I'm trying to use 2 databases for Spring Boot. However, it says could not autowire.

No beans of EntityManagerFactoryBuild type found

I'm new to Spring Boot, and I'm using MySQL 8, Spring Boot 2 and Java 12.

I have included student & adms configure files and repository files here. File structure is

com.project.attendance
        -configure
        -model
        -repository
        -dao
        -controller

StudentConfigure class configuration

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        basePackages = "com.project.attendance.repository.student",
        entityManagerFactoryRef = "studentEntityManager",
        transactionManagerRef = "studentTransactionManager"
)

public class StudentConfigure {

    @Primary
    @Bean(name="studentDataSource")
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource studentDataSource(){
        return DataSourceBuilder.create().build();
    }

    @Primary
    @Bean(name="studentEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("studentDataSource") DataSource dataSource){
        return builder
                .dataSource(dataSource)
                .packages("com.project.attendance.dao.student")
                .persistentUnit("sampledb")
                .build();
    }

    @Primary
    @Bean(name="studentTransactionManager")
    public PlatformTransactionManager studentTransactionManager(
            @Qualifier("studentEntityManagerFactory") EntityManagerFactory studentEntityManagerFactory){
        return new JpaTransactionManager(studentEntityManagerFactory);
    }

}

AdmsConfigure configure class implementation

  package com.project.attendance.configure;

    import javax.sql.DataSource;

    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories(
            basePackages = {"com.project.attendance.repository.adms"},
            entityManagerFactoryRef = "admsEntityManager",
            transactionManagerRef = "admsTransactionManager"
    )
    @ComponentScan(basePackages = "com.project.attendance.repository.adms")

    public class AdmsConfigure {

        @Bean(name="admsDataSource")
        @ConfigurationProperties(prefix = "spring.datasource2")
        public DataSource admsDataSource(){
            return DataSourceBuilder.create().build();
        }

        @Bean(name="admsEntityManagerFactory")
        public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("admsDataSource") DataSource dataSource){
            return builder
                    .dataSource(dataSource)
                    .packages("com.project.attendance.dao.adms")
                    .persistentUnit("adms")
                    .build();
        }

        @Primary
        @Bean(name="admsTransactionManager")
        public PlatformTransactionManager admsTransactionManager(
                @Qualifier("admsEntityManagerFactory") EntityManagerFactory admsEntityManagerFactory){
            return new JpaTransactionManager(admsEntityManagerFactory);
        }
    }

Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)

spring.datasource.url = jdbc:mysql://localhost:3306/sampledb?useSSL=false
spring.datasource.username = root
spring.datasource.password =root

spring.datasource2.url = jdbc:mysql://localhost:3306/adms?useSSL=false
spring.datasource2.username = root
spring.datasource2.password =root
logging.level.root=WARN
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Ayesh17
  • 153
  • 1
  • 1
  • 16
  • Possible duplicate of [Spring Boot Configure and Use Two DataSources](https://stackoverflow.com/questions/30337582/spring-boot-configure-and-use-two-datasources) – Maheshwar Ligade Sep 05 '19 at 09:26
  • https://medium.com/@joeclever/using-multiple-datasources-with-spring-boot-and-spring-data-6430b00c02e7 with this link you will get your answer – Maheshwar Ligade Sep 05 '19 at 09:27

2 Answers2

0

I think the problem is that in the AdmsConfigure class you are referencing admsEntityManager as an entityManagerFactoryRef. Instead you should reference the actual factory not the manager.

The code should look like this

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        basePackages = {"com.project.attendance.repository.adms"},
        entityManagerFactoryRef = "admsEntityManagerFactory",
        transactionManagerRef = "admsTransactionManager"
)
@ComponentScan(basePackages = "com.project.attendance.repository.adms")
public class AdmsConfigure {

    @Bean(name="admsDataSource")
    @ConfigurationProperties(prefix = "spring.datasource2")
    public DataSource admsDataSource(){
        return DataSourceBuilder.create().build();
    }

    @Bean(name="admsEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("admsDataSource") DataSource dataSource){
        return builder
                .dataSource(dataSource)
                .packages("com.project.attendance.dao.adms")
                .persistentUnit("adms")
                .build();
    }

    @Bean(name="admsTransactionManager")
    public PlatformTransactionManager admsTransactionManager(
            @Qualifier("admsEntityManagerFactory") EntityManagerFactory admsEntityManagerFactory){
        return new JpaTransactionManager(admsEntityManagerFactory);
    }
}

In addition, you should not be annotating both of yours PlatformTransactionManagers with @Primary annotation.

toucheqt
  • 725
  • 2
  • 8
  • 15
  • thx a lot but it still shows the same error and yeah using @Primary annotation in the adms PlatformTransactionManager was a mistake – Ayesh17 Sep 09 '19 at 04:17
0

Try with the following changes:

  1. remove the @Primary from bean. This is because it contains the @Primary annotation. This annotation is useful when we want to specify which bean of a certain type should be injected by default.

    And in case we require the other bean at some injection point, we would need to specifically indicate it. We can do that via the @Qualifier annotation

    It's worth noting that if both the @Qualifier and @Primary annotations are present, then the @Qualifier annotation will have precedence.

  2. use @Qualifier to identify the bean. The @Qualifier annotation is used to resolve the autowiring conflict when there are multiple beans of the same type.

    .......
     public class AdmsConfigure {
    
        @Bean
        @Qualifier("admsDataSource")
        @ConfigurationProperties(prefix = "spring.datasource2")
        public DataSource admsDataSource(){
            return DataSourceBuilder.create().build();
        }
    
        @Bean
        @Qualifier("admsEntityManagerFactory")
        public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("admsDataSource") DataSource dataSource){
            return builder
                    .dataSource(dataSource)
                    .packages("com.project.attendance.dao.adms")
                    .persistentUnit("adms")
                    .build();
        }
    
        @Bean
        @Qualifier("admsTransactionManager")
        public PlatformTransactionManager admsTransactionManager(
                @Qualifier("admsEntityManagerFactory") EntityManagerFactory admsEntityManagerFactory){
            return new JpaTransactionManager(admsEntityManagerFactory);
        }
    }
    

same changes in StudentConfiguration applicable

MangduYogii
  • 935
  • 10
  • 24