Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot 2.0.0.M4 & Hibernate 5.2.11.Final could not find bean of type EntityManagerFactoryBuilder

I have clearly what seems to be some configuration issue, but I've been unable to resolve this myself. I have hope you guys could help me?

None of the examples I find indicate having to create a bean for EntityManagerFactoryBuilder so what's the issue.

I am attempting to configure completely separate datasources, including different entity managers etc..

My Error:


APPLICATION FAILED TO START


Description:

Parameter 0 of method entityManagerFactory 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.

My DataSourceConfiguration

package ...;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
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.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;

@Configuration
@EnableTransactionManagement
public class DataSourceConfiguration {


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



    @Primary
    @Bean(name = "myEntityManager")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder factoryBuilder,
                                                                       @Qualifier("myEntityManager") DataSource bds) {
        ...
    }
}

My Application

@SpringBootApplication(exclude = {
        DataSourceAutoConfiguration.class,
        HibernateJpaAutoConfiguration.class,
        JpaRepositoriesAutoConfiguration.class,
        DataSourceTransactionManagerAutoConfiguration.class
})

My Pom

like image 491
eztinkerdreams Avatar asked Oct 04 '17 21:10

eztinkerdreams


People also ask

What is the difference between spring 4 and 5?

So Spring 4 had to support Java 6, 7 and 8. To maintain the backward compatibility, Spring framework didn't adapted many new features which Java 8 brought with itself e.g. Lambda programming. Spring 5 has baseline version 8, so it uses many new features of Java 8 and 9 as well.

What does Spring Boot do?

Spring Boot helps developers create applications that just run. Specifically, it lets you create standalone applications that run on their own, without relying on an external web server, by embedding a web server such as Tomcat or Netty into your app during the initialization process.

What is generated security password in spring boot?

The log “Using generated security password:” appears in the startup of the spring boot application. This log is due to default security configuration. This can be disabled, removed or customized using configurations.


2 Answers

By excluding HibernateJpaAutoConfiguration you are turning off creating EntityManagerFactoryBuilder bean.

By default EntityManagerFactoryBuilder bean is produced by JpaBaseConfiguration#entityManagerFactoryBuilder(JpaVendorAdapter, ObjectProvider).

There is only one JpaBaseConfiguration implementation - HibernateJpaConfiguration, which is activated if:

  • there is only one DataSource candidate (or one is marked as @Primary);
  • HibernateJpaAutoConfiguration conditions are true - check HibernateJpaAutoConfiguration class.

You should either create and configure LocalContainerEntityManagerFactoryBean without builder (like you did in your own answer), or create EntityManagerFactoryBuilder in your configuration manually like this:

@Bean
public EntityManagerFactoryBuilder entityManagerFactoryBuilder() {
    return new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter(), new HashMap<>(), null);
}
like image 165
Snarkovski Avatar answered Sep 27 '22 22:09

Snarkovski


In response to @Albert Bos questions...

I think what did it was this.

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        basePackageClasses = { MyEntityRepository.class },
        repositoryBaseClass = EntityRepositoryImpl.class,
        transactionManagerRef = "myTransactionManager",
        entityManagerFactoryRef = "myEntityManagerFactory"
)
public class MyDataSourceConfiguration { ...

This is my datasource configuration.

@Bean(name = DATASOURCE_NAME + "DataSource")
public DataSource dataSource(@Qualifier(DATASOURCE_NAME + "DataSourceProperties") DataSourceProperties dataSourceProperties) 
{
    return DataSourceBuilder.create()
            .url(dataSourceProperties.getUrl())
            .username(dataSourceProperties.getUsername())
            .password(dataSourceProperties.getPassword())
            .driverClassName(dataSourceProperties.getDriverClassName())
            .build();
}

@Bean(name = DATASOURCE_NAME + "EntityManagerFactory")
@PersistenceContext(unitName = DATASOURCE_NAME + "PersistenceUnit")
public EntityManagerFactory entityManagerFactory(
        @Qualifier(DATASOURCE_NAME + "JpaProperties") Properties jpaProperties,
        @Qualifier(DATASOURCE_NAME + "DataSource") DataSource dataSource,
        @Qualifier(DATASOURCE_NAME + "JpaVendorAdapter") JpaVendorAdapter jpaVendorAdapter) 
{
    LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
    factoryBean.setDataSource(dataSource);
    factoryBean.setJpaProperties(jpaProperties);
    factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
    factoryBean.setPackagesToScan(MyEntity.class.getPackage().getName());
    factoryBean.setPersistenceUnitName(DATASOURCE_NAME + "PersistenceUnit");
    factoryBean.afterPropertiesSet();
    return factoryBean.getObject();
}

@Bean(name = DATASOURCE_NAME + "TransactionManager")
public PlatformTransactionManager transactionManager(@Qualifier(DATASOURCE_NAME + "EntityManagerFactory") EntityManagerFactory entityManagerFactory) 
{
    JpaTransactionManager txManager = new JpaTransactionManager();
    txManager.setEntityManagerFactory(entityManagerFactory);
    return txManager;
}

And Application Configuration

@SpringBootApplication(exclude = {
        LiquibaseAutoConfiguration.class,
        DataSourceAutoConfiguration.class,
        ValidationAutoConfiguration.class,
        HibernateJpaAutoConfiguration.class,
        JpaRepositoriesAutoConfiguration.class,
        DataSourceTransactionManagerAutoConfiguration.class
})
like image 31
eztinkerdreams Avatar answered Sep 27 '22 22:09

eztinkerdreams