SheppardDigital
SheppardDigital

Reputation: 3255

Spring Boot EntityManagerFactoryBuilder not autowired

In a Spring Boot application I'm trying to setup multiple database connections. I've started building the primary datasource, but I'm getting the following error on the mySqlEntityManagerFactory method.

Could not autowire. no beans of EntityManagerFactoryBuilder

import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.PersistenceContext;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

@Configuration
@Transactional
@EnableTransactionManagement
@EnableJpaRepositories(
        basePackages = "digital.sheppard.dao",
        entityManagerFactoryRef = "entityManager",
        transactionManagerRef = "transactionManager")
public class PrimaryDBConfig {

    @Bean(name="dataSource")
    @Primary
    @ConfigurationProperties(prefix = "primary.datasource.mysql")
    public DataSource mysqlDataSource() {
        return DataSourceBuilder.create().build();
    }

    @PersistenceContext(unitName = "primary")
    @Primary
    @Bean(name = "entityManager")
    public LocalContainerEntityManagerFactoryBean mySqlEntityManagerFactory(EntityManagerFactoryBuilder builder) {
        return builder.dataSource(mysqlDataSource()).persistenceUnit("primary").properties(jpaProperties())
                .packages("digital.sheppard.model").build();
    }

    private Map<String, Object> jpaProperties() {
        Map<String, Object> props = new HashMap<String, Object>();
        props.put("hibernte.ejb.naming_strategy", "org.hibernate.cfg.ImprovedNamingStrategy");
        props.put("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");

        return props;
    }

}

How would I autowire the EntityManagerFactoryBuilder?

I'm trying to follow the code on this blog https://raymondhlee.wordpress.com/2015/10/31/configuring-multiple-jpa-entity-managers-in-spring-boot/

Here's the main application class if it's helpful

@Configuration
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
@ComponentScan
public class Application extends SpringBootServletInitializer {

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

}

Upvotes: 28

Views: 30893

Answers (9)

andreas.petter
andreas.petter

Reputation: 101

For me the reason was a wrong import, so I advise everybody to look at the often overlooked import section of your configuration class. There is a Hibernate class named the same as the springframework one. Of course you should choose the spring one...

Upvotes: 10

omkar sirra
omkar sirra

Reputation: 726

For me , removing @Primary on multiple Data sources, which was added by mistake fixed the issue

Upvotes: 0

Alexandre Souza Peron
Alexandre Souza Peron

Reputation: 19

Change parameter name builder to entityManagerFactoryBuilder to inject bean present in JpaBaseConfiguration.class

Upvotes: 1

Archit
Archit

Reputation: 961

The exception is due to public LocalContainerEntityManagerFactoryBean mySqlEntityManagerFactory(EntityManagerFactoryBuilder builder) { which expects a bean of EntityManagerFactoryBuilder.

I checked the reference link, I am not sure if that code will work.

Typically, one creates an instance of LocalContainerEntityManagerFactoryBean and initializes it as per need. In your case you can do

  LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
  em.setDataSource(mysqlDataSource());
  em.setPersistenceUnitName("primary");
  em.setPackagesToScan(new String[] { "digital.sheppard.model" });

  JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
  em.setJpaVendorAdapter(vendorAdapter);
  em.setJpaProperties(jpaProperties());

The persistence unit name should be same as defined in persistence.xml, though the file is now optional when using Spring JPA.

For a non spring version check out https://stackoverflow.com/a/26814642/776548

Also

  • since you are initializing EntityManagerFactory by yourself, we will have to exclude DataSourceAutoConfiguration.class.
  • @Primary is only required if you want multiple datasources. If you have only one, consider removing the annotation, and add it when you need to have multiple data sources

Upvotes: 2

Akash
Akash

Reputation: 593

Couple of possibilities : You need to add the @EnableJpaRepositories(basePackages = {"your.pkg.here"}) to the Application . This tells Spring Data to look for your repository classes under the specified package.

Upvotes: -1

cehdmoy
cehdmoy

Reputation: 44

It could be, notice that just could be, your main class is not at the top of the "class tree". Spring needs to scan all classes that are a child (according to package convention) starting from the main class.

Maybe you would read https://www.baeldung.com/spring-component-scanning

If your classes aren't been read by spring scan, they will never be into spring context.

Upvotes: -1

Y.Ido
Y.Ido

Reputation: 343

I think you should remove this code

@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})

Upvotes: 2

Mathan
Mathan

Reputation: 7

Have you tried to remove your exclusion of 'DataSourceAutoConfiguration' ?

Using '@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})' prevent a lot of beans from beeing created.

If you got a problem when using a datasource and adding this is your solution, maybe it's not the right one.

Know that spring boot detect the presence of certain classes in the classpath. If you're using maven, it's reading all classes from all dependencies.

So consider let this DataSourceAutoConfiguration.class running;

cheers

Upvotes: 0

D.Mummy
D.Mummy

Reputation: 25

it was caused by your ide software,set up these options enter image description here

Upvotes: -7

Related Questions