Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument;

I am getting this error in my code.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'roleRepository': Cannot create inner bean '(inner bean)#7540dc57' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property 'entityManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#7540dc57': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available

I saw these:

Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument

NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' available

NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' is defined

None of them answers my question. The thing is I was able the solve the problem but I have a question about it.

Let me share my related code and then ask the question I have.

@Configuration
@EnableTransactionManagement 
public class HibernateConfig {

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerF() {
    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setDataSource(dataSource());
    em.setPackagesToScan(new String[] {"com.gitreporter"});
    JpaVendorAdapter jpaAdapter = new HibernateJpaVendorAdapter();
    em.setJpaVendorAdapter(jpaAdapter);
    em.setJpaProperties(jpaProperties());

    return em;
}

@Bean
public PlatformTransactionManager jpaTransactionManager(EntityManagerFactory emf) {
    JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
    jpaTransactionManager.setEntityManagerFactory(emf);

    return jpaTransactionManager;
}

private final Properties jpaProperties() {
    Properties properties = new Properties();
    properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");

    return properties;
}


@Bean
public DataSource dataSource() {
    BasicDataSource dataSource = new BasicDataSource();
    dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
    dataSource.setUrl("jdbc:mysql://localhost:3306/MyDBNAME?useSSL=false");
    dataSource.setUsername("username");
    dataSource.setPassword("password");

    return dataSource;
}

The problem was on this line:

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerF() {

I changed the medhod name to entityManagerFactory like so:

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {

Making the name of the factory bean in the context equal to "entityManagerFactory" since by default the name of the bean will be equal to the method name unless explicitly specified.

My question: Is there a place in JPA API that "by convention" it is looking for an EntityManagerFactory bean named "entityManagerFactory" inside Spring container? Why is it not working when the name of the method is "entityManagerF"?

Here is the rest of the code:

@NoRepositoryBean
public interface GenericRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {

public List<T> findByAttributeContainsText(String attributeName, String text);

}

public class GenericRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID>
    implements GenericRepository<T, ID> {

private EntityManager entityManager;

public GenericRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
    super(entityInformation, entityManager);
    this.entityManager = entityManager;
 }
}


public interface RoleRepository extends GenericRepository<Role, Long> {

}
like image 962
honor Avatar asked Nov 04 '18 11:11

honor


1 Answers

I found the answer.

Checkout the documentation for @EnableJpaRepositories annotation.

In the optional elements you will see this:

entityManagerFactoryRef Configures the name of the EntityManagerFactory bean definition to be used to create repositories discovered through this annotation.

Go down the page to the details and you will see this:

entityManagerFactoryRef

public abstract String entityManagerFactoryRef

Configures the name of the EntityManagerFactory bean definition to be used to create repositories discovered through this annotation. Defaults to entityManagerFactory.

Returns:

Default: "entityManagerFactory"

So this "conventional" default configuration comes from @EnableJpaRepositories annotation itself.

like image 134
honor Avatar answered Sep 30 '22 05:09

honor