15

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

弹簧上下文配置:

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

3 回答 3

5

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

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

即这样的东西:

@Bean(name = "entityManagerFactoryBean")
public LocalContainerEntityManagerFactoryBean ...
于 2013-10-29T09:17:33.940 回答
3

使用

@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);
    }
于 2018-04-23T13:26:51.767 回答
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();
    }
于 2013-10-31T06:33:31.307 回答