2013-10-29 72 views
2

我已經使用了基於Java的配置。當我使用jpa庫時,我得到can not create inner bean exception of type shared entity manger creator無法創建類型爲[org.springframework.orm.jpa.SharedEntityManagerCreator]的內部bean'(inner bean)'?

春CONTEX配置:

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

} 

Webintializer:

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

    } 

Controller類:

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

回答

3

的一切,如果你在你的異常跟蹤,你會密切關注第一看到ContextLoaderListner實際上是抱怨No bean named 'entityManagerFactory' is defined作爲無法創建personRepository的根本原因。

因爲我不知道確切的項目結構是什麼,你可以試着把LocalContainerEntityManagerFactoryBean這個bean的名字加上,這樣Spring就可以找到並注入它。

即事情是這樣的:

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

最後,我得到了這個解決方案。我在配置文件中做了這些更改。

它成功執行。

@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(); 
    } 
+0

你會突出顯示你改變了什麼嗎? –

相關問題