当前位置: 首页 > 知识库问答 >
问题:

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

赏阳嘉
2023-03-14

我的代码中出现了这个错误。

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

我看到了这些:

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

没有名为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> {

}

共有2个答案

慕容恩
2023-03-14

是的,我想是的。在您的例子中,Spring确实预先配置了beanentityManagerFactory

@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).

并且,看到您的hibernate配置,

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 提供对该问题的更深入了解。

曾典
2023-03-14

我找到了答案。

签出@EnableJpaRepositories注释的文档。

在可选元素中,您将看到以下内容:

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

向下查看详细信息,您将看到以下内容:

entityManagerFactoryRef

公共抽象字符串entityManagerFactoryRef

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

返回:

默认:"entityManagerFactory"

所以这个“常规”默认配置来自@EnableJpaRepository注释本身。

 类似资料:
  • 我刚刚迁移到spring JPA技术,并设法将我的简单jersey hibernate项目更改为具有自定义crudrepository的spring JPA。但我不能处理自动配置EntityManagerFactorybean。下面是我的代码: application.properties: 应用程序: 错误日志报告: LogHandler: 错误日志: pom。xml 最后是我的堆栈跟踪: 谢谢

  • 我正在尝试从我的主方法创建一个Spring bean。 我已将此bean配置为具有特定属性。这些值是在由@Configuration注释的SpringConfig类中指定的。 bean是使用Spring Application Context在我的main()方法中创建的。bean成功启动,但它没有我在SpringConfig类中指定的属性。我不明白为什么? 我可能已经确定了问题的原因:这个bea

  • 问题内容: 大家好,我正在尝试在选项卡中列出文本数据,这是我的方法 无法解析构造函数ArrayAdapter 的方法,这是我的主要活动。任何帮助将不胜感激,我仍然是一个noobie 。 问题答案: 更改 至 你可以在使用。

  • 问题内容: 有人可以帮我这段代码。当前它将在第4行进行投诉:webDriver =新的FirefoxDriver(ff_ep_profiles)说它无法解析构造函数。我需要加载扩展程序,因此我正在创建配置文件 问题答案: 在使用 Selenium v​​3.11.x , GeckoDriver v0.20.0 和 Firefox Quantum v59.0.2时 ,可以使用不同的选项来调用新的/现

  • 我正在浏览hibernate留档,文档说hibernate需要为我们所有的持久类提供一个no-arg构造函数: 无参数构造函数是所有持久类的要求;Hibernate必须使用Java反射为您创建对象。构造器可以是私有的,但是在没有字节码插装的情况下,运行时代理生成和有效的数据检索需要包或公共可见性。 但是当我通过创建一个没有任何无参数构造函数的POJO类并放置一个接受参数的构造函数来创建一个示例程序

  • 本文向大家介绍解析C++中构造函数的默认参数和构造函数的重载,包括了解析C++中构造函数的默认参数和构造函数的重载的使用技巧和注意事项,需要的朋友参考一下 C++构造函数的默认参数 和普通函数一样,构造函数中参数的值既可以通过实参传递,也可以指定为某些默认值,即如果用户不指定实参值,编译系统就使形参取默认值。 【例】 程序运行结果为: 程序中对构造函数的定义(第12-16行)也可以改写成参数初始化