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

2

7

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

Wheal answered 4/10, 2017 at 21:44 Comment(3)
Any luck solving this? I have the same issue with 2.0.0.RELEASECoastward
I do have this working with 2.0.0.RELEASE but it was so long ago I don't remember what I did. My datasource configuration is quite complex, so I can't really post it here.Wheal
I am facing the same issue with 2.1.1 RELEASEFotinas
W
3

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
})
Wheal answered 3/4, 2018 at 15:4 Comment(0)
U
19

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);
}
Underdrawers answered 12/7, 2018 at 12:28 Comment(0)
W
3

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
})
Wheal answered 3/4, 2018 at 15:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.