繁体   English   中英

设置构造函数参数时无法解析对bean“entityManagerFactory”的引用;

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

我在我的代码中收到此错误。

org.springframework.beans.factory.BeanCreationException:创建名为'roleRepository'的bean时出错:在设置bean属性'entityManager时,无法创建[org.springframework.orm.jpa.SharedEntityManagerCreator]类型的内部bean'(内部bean)#7540dc57' “; 嵌套异常是org.springframework.beans.factory.BeanCreationException:创建名为'(内部bean)#7540dc57'的bean时出错:在设置构造函数参数时无法解析对bean'entalManagerFactory'的引用; 嵌套异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:没有名为'entityManagerFactory'的bean可用

我看到了这些:

在设置构造函数参数时无法解析对bean'entalManagerFactory'的引用

NoSuchBeanDefinitionException:没有名为“entityManagerFactory”的bean可用

NoSuchBeanDefinitionException:没有定义名为“entityManagerFactory”的bean

他们都没有回答我的问题。 问题是我能够解决问题,但我有一个问题。

让我分享我的相关代码,然后问我的问题。

@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;
}

问题出在这条线上:

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerF() {

我将medhod名称更改为entityManagerFactory,如下所示:

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {

使上下文中的工厂bean的名称等于“entityManagerFactory”,因为默认情况下,除非明确指定,否则bean的名称将等于方法名称。

我的问题:JPA API中是否存在“按惯例”它在Spring容器中寻找名为“entityManagerFactory”的EntityManagerFactory bean? 当方法的名称是“entityManagerF”时,为什么它不起作用?

这是代码的其余部分:

@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> {

}

我找到了答案。

查看@EnableJpaRepositories注释的文档

在可选元素中,您将看到:

entityManagerFactoryRef配置要用于创建通过此批注发现的存储库的EntityManagerFactory bean定义的名称。

在页面下方查看详细信息,您将看到:

entityManagerFactoryRef

public abstract String entityManagerFactoryRef

配置要用于创建通过此批注发现的存储库的EntityManagerFactory bean定义的名称。 默认为entityManagerFactory

返回:

默认值:“entityManagerFactory”

因此,这种“常规”默认配置来自@EnableJpaRepositories注释本身。

是的我相信。 在您的情况下,Spring确实预先配置了一个bean entityManagerFactory

来自@EnableAutoConfiguration的javadoc的摘录说

        Enable auto-configuration of the Spring Application Context, attempting to guess and configure beans that you are likely to need. Auto-configuration classes are usually applied based on your classpath and what beans you have defined. For example, if you have tomcat-embedded.jar on your classpath you are likely to want a TomcatServletWebServerFactory (unless you have defined your own ServletWebServerFactory bean).

并且,看到你的休眠配置,

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

    return properties;

...我想,这必须被调用,这是从JpaBaseConfiguration派生的

@Configuration
@ConditionalOnSingleCandidate(DataSource.class)
class HibernateJpaConfiguration extends JpaBaseConfiguration {

并且JpaBaseConfiguration确实有entityManagerFactory的bean定义,这是你试图覆盖的。

@Bean
@Primary
@ConditionalOnMissingBean({ LocalContainerEntityManagerFactoryBean.class,
        EntityManagerFactory.class })
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
        EntityManagerFactoryBuilder factoryBuilder) {
    Map<String, Object> vendorProperties = getVendorProperties();
    customizeVendorProperties(vendorProperties);
    return factoryBuilder.dataSource(this.dataSource).packages(getPackagesToScan())
            .properties(vendorProperties).mappingResources(getMappingResources())
            .jta(isJta()).build();
}

编辑: -感谢OP的回答。 因此,它甚至可以用于通过类似的声明提供自定义bean名称

@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerF",
)         

https://stackoverflow.com/a/45665826/5107365上的另一个stackoverflow线程提供了对此问题的更深入的了解。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM