【问题标题】:Cannot create inner bean '(inner bean)' of type [org.springframework.orm.jpa.SharedEntityManagerCreator]?无法创建 [org.springframework.orm.jpa.SharedEntityManagerCreator] 类型的内部 bean '(inner bean)'?
【发布时间】:2013-11-08 07:45:02
【问题描述】:

我使用了基于 Java 的配置。当我使用 jpa 存储库时,我得到了 can not create inner bean exception of type shared entity manger creator

Spring 上下文配置:

@Configuration
@ComponentScan(basePackages = { "com.sample.proj.controller" })
@EnableWebMvc
@EnableTransactionManagement
@EnableJpaRepositories("com.sample.proj.domain")
@PropertySource("classpath:application.properties")
public class ServletContextConfig {

    private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
    private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
    private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
    private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
    private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
    private static final String PROPERTY_NAME_HIBERNATE_FORMAT_SQL = "hibernate.format_sql";
    private static final String PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY = "hibernate.ejb.naming_strategy";
    private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
    private static final String PROPERTY_NAME_HIBERNATE_HBN2DDL_SQL = "hibernate.hbm2ddl.auto";

    @Resource
    private Environment environment;

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();

        dataSource.setDriverClassName(environment
                .getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
        dataSource.setUrl(environment
                .getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
        dataSource.setUsername(environment
                .getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
        dataSource.setPassword(environment
                .getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));

        return dataSource;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean()
            throws Exception {
        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactoryBean.setDataSource(dataSource());
        entityManagerFactoryBean
                .setPackagesToScan(new String[] { "com.sample.proj.domain" });
        entityManagerFactoryBean
                .setPersistenceProviderClass(HibernatePersistence.class);

        Properties jproperties = new Properties();
        jproperties.put("hibernate.dialect", environment
                .getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
        jproperties.put("hibernate.format_sql", environment
                .getRequiredProperty(PROPERTY_NAME_HIBERNATE_FORMAT_SQL));
        jproperties.put("hibernate.ejb.naming_strategy", environment
                .getRequiredProperty(PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY));
        jproperties.put("hibernate.show_sql", environment
                .getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
        jproperties.put("hibernate.hbm2ddl.auto", environment
                .getRequiredProperty(PROPERTY_NAME_HIBERNATE_HBN2DDL_SQL));
        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
        entityManagerFactoryBean.setJpaProperties(jproperties);
        return entityManagerFactoryBean;
    }

}

网络初始化器:

@Override
public void onStartup(ServletContext container) {
        // Create the 'root' Spring application context
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(ServletContextConfig.class);

        // Manage the lifecycle of the root application context
        container.addListener(new ContextLoaderListener(rootContext));

        // Create the dispatcher servlet's Spring application context
        AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
        dispatcherContext.register(ServletContextConfig.class);

        // Register and map the dispatcher servlet
        ServletRegistration.Dynamic dispatcher = container.addServlet(
                "dispatcher", new DispatcherServlet(dispatcherContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
}

存储库:

    public interface PersonRepository extends JpaRepository<Person, String> {

    }

服务类:

    @Service
    @Transactional
    public class PersonService {

        @Autowired
        PersonRepository personRepository;

        public Person saveDetails(Person person) {
            // System.out.println("Service Class:Person Name:"+
            // person.getPersonName());
            System.out.println("Executed");
            return person;
        }

    }

控制器类:

    @RequestMapping(value = "/addPerson", method = RequestMethod.POST)
        public String addperson(@RequestParam("personName") String name,
                @RequestParam("personAddress") String address, Model model) {
            System.out.println("Name:" + name);
            System.out.println("Address:" + address);
            Person person = new Person();
            person.setPersonId(1);
            person.setPersonName(name);
            person.setPersonAddress(address);
            personService.saveDetails(person);
            model.addAttribute("result", "Your record inserted successfully");

            return HOME_VIEW;
        }

领域类:

@Entity
@Table(name = "PERSON")
public class Person implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    @Id
    private Integer personId;
    private String personName;
    private String personAddress;

    //getters and setters... 

}

异常堆栈跟踪如下:

SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
        org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personRepository': Cannot create inner bean '(inner bean)' 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)#1': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' is defined
            at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:282)
            at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:126)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1391)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1132)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:522)
            at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
            at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
            at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
            at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
            at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
            at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:589)
            at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
            at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
            at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:383)
            at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:283)
            at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
            at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4791)
            at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5285)
            at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
            at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
            at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
            at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:618)
            at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:650)
            at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1582)
            at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
            at java.util.concurrent.FutureTask.run(FutureTask.java:262)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
            at java.lang.Thread.run(Thread.java:744)

【问题讨论】:

    标签: spring spring-mvc jpa spring-data


    【解决方案1】:

    首先,如果您仔细查看异常跟踪,您会发现 ContextLoaderListner 实际上是在抱怨 No bean named 'entityManagerFactory' is defined 是无法创建 personRepository 的根本原因。

    由于我不知道确切的项目结构是什么,您可以尝试将 bean 名称与 LocalContainerEntityManagerFactoryBean 一起,以便 Spring 可以找到并注入它。

    即像这样:

    @Bean(name = "entityManagerFactoryBean")
    public LocalContainerEntityManagerFactoryBean ...
    

    【讨论】:

      【解决方案2】:

      使用

      @EnableJpaRepositories("some.package.ref.other.than.default")

      在 Application.java 主文件中为我解决了问题。

      我的大部分文件都位于包中

      com.example.cortifero

      因此,我编写了这样的代码(Application.java):

      @EnableJpaRepositories(basePackages="com.example.cortifero.jpa.service") //notice this line
      @SpringBootApplication
      public class Application {
      
          public static void main(String[] args) {
              SpringApplication.run(Application.class, args);
          }
      

      【讨论】:

        【解决方案3】:

        最后,我得到了这个解决方案。我在配置文件中进行了此更改。

        成功执行。

        @Configuration
        @EnableTransactionManagement
        @EnableJpaRepositories(basePackages = { "com.sample.proj.repo" })
        @PropertySource("classpath:application.properties")
        public class JpaConfig {
        
            private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
            private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
            private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
            private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
        
            @Resource
            private Environment environment;
        
            @Bean
            public DataSource dataSource() {
                DriverManagerDataSource dataSource = new DriverManagerDataSource();
        
                dataSource.setDriverClassName(environment
                        .getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
                dataSource.setUrl(environment
                        .getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
                dataSource.setUsername(environment
                        .getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
                dataSource.setPassword(environment
                        .getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
        
                return dataSource;
            }
        
            @Bean
            public PlatformTransactionManager transactionManager() {
                EntityManagerFactory factory = entityManagerFactory();
                return new JpaTransactionManager(factory);
            }
        
            @Bean
            public EntityManagerFactory entityManagerFactory() {
                HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
                vendorAdapter.setGenerateDdl(Boolean.TRUE);
                vendorAdapter.setShowSql(Boolean.TRUE);
                LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
                factory.setJpaVendorAdapter(vendorAdapter);
                factory.setPackagesToScan("com.sample.proj.domain");
                factory.setDataSource(dataSource());
                factory.afterPropertiesSet();
                factory.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver());
                return factory.getObject();
            }
        
            @Bean
            public HibernateExceptionTranslator hibernateExceptionTranslator() {
                return new HibernateExceptionTranslator();
            }
        

        【讨论】:

        • 您会突出显示您所做的更改吗?
        • 当您遇到同样的问题但他们实际上并没有概述他们所做的更改时非常令人沮丧。
        • 请概述所做的更改很难找到解决问题的方法。
        • @SabirKhan, Cris Milburn, Balu 谁能发帖为你们解决了这个错误?遇到同样的问题,但似乎找不到解决方案。
        猜你喜欢
        • 2012-03-05
        • 2021-08-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-17
        相关资源
        最近更新 更多