因此,我正在尝试构建一个使用Hibernate写入MySQL数据库的应用程序,并且花了很长时间尝试使其运行。简而言之,即使我已配置并自动连线,也看不到会话。这是我明智的代码。

首先配置该应用程序:

@EnableBatchProcessing
@SpringBootApplication(scanBasePackages="com.lcbo")
@EnableIntegration
public class BatchConfig {

@Autowired
private JobBuilderFactory jobBuilderFactory;

@Autowired
private StepBuilderFactory stepBuilderFactory;

@Bean
public Job processLCBOInventory(@Qualifier("getCurrentLCBODataStep") final Step getCurrentLCBODataStep,
                                @Qualifier("getLCBOStoreDataStep") final Step getLCBOStoreDataStep,
                                final JobExecutionListenerConfig jelcListener
                                ) {
    return jobBuilderFactory
            .get("processLCBOInventory")
            .incrementer(new RunIdIncrementer())
            .start(getCurrentLCBODataStep)
            .next(getLCBOStoreDataStep)
            .listener(jelcListener)
            .build();

}

@Bean
public Step getLCBOStoreDataStep(final LCBOStoreReader lcboStoreReader,
                                 final LCBOStoreProcessor lcboStoreProcessor,
                                 final LCBOStoreWriter lcboStoreWriter,
                                 final ExecutionContextPromotionListener listener) throws Exception {

    return stepBuilderFactory
            .get("getLCBOStoreDataStep")
            .<LCBOStore, LCBOStore>chunk(inventoryTrackerProperties.getDefaults().getChunkSize())
            .reader(lcboStoreReader.read())
            .processor(lcboStoreProcessor)
            .writer(lcboStoreWriter)
            .listener(listener)
            .build();
}


然后,作者:

@Component
public class LCBOStoreWriter extends HibernateItemWriter<LCBOStore> {

        @Autowired
private LCBOStoreService lcboStoreService;

@Autowired
private DatabaseConfig dbConfigy;

private static final Logger log = LoggerFactory.getLogger(LCBOStoreWriter.class);

@Override
public void write(List<? extends LCBOStore> lcboStoreItems) {

    for (LCBOStore lcboStoreItem : lcboStoreItems) {
        lcboStoreService.addNewStore(lcboStoreItem);
    }

}


以及DatabaseConfig文件的内容:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.lcbo.domain")
public class DatabaseConfig {

    @Autowired
    private LCBOInventoryTrackerProperties properties;

    @Bean
    public EntityManagerFactory entityManagerFactory() throws SQLException {

        final LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
        factoryBean.setDataSource(dataSource());
        factoryBean.setJpaDialect(new HibernateJpaDialect());
        factoryBean.setJpaProperties(getHibernateProperties());
        factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        factoryBean.setPackagesToScan("com.lcbo.domain");
        factoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
        factoryBean.setPersistenceUnitName("persistenceUnit");
        factoryBean.afterPropertiesSet();


        return factoryBean.getObject();
    }

    @Bean(destroyMethod = "")
    public DataSource dataSource() throws SQLException {
        BasicDataSource dataSource = new BasicDataSource();

        dataSource.setDriverClassName(properties.getDb().getDriver());
        dataSource.setUrl(properties.getDb().getUrl());
        dataSource.setUsername(properties.getDb().getUsername());
        dataSource.setPassword(properties.getDb().getPassword());

        return dataSource;
    }


甚至尝试过SessionFactory本身,就像这样

public LocalSessionFactoryBean getSessionFactory() throws SQLException {
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
    sessionFactory.setDataSource(dataSource());
    sessionFactory.setPackagesToScan(new String[] { "com.bytestree.model" });
    sessionFactory.setHibernateProperties(getHibernateProperties());

    return sessionFactory;
}


但没有骰子我还尝试将SessionFactory实例注入HibernateItemWriter附带的setSessionFactory中,同样没有骰子。

我知道我出了点问题,问题是它期望SessionFactory放置在哪里,以便应用程序对它进行调整,或者我是否已将该编写器配置为几乎完全正确的位置?

编辑:根据要求,运行此代码后在intellj中显示的stacktrace。

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'LCBOInventoryWriter' defined in file [C:\workspace\LCBOInventoryTracker\target\classes\com\lcbo\writer\LCBOInventoryWriter.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Either HibernateOperations or SessionFactory must be provided
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
    at com.lcbo.config.LCBOBatchConfig.main(LCBOBatchConfig.java:157) [classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_102]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_102]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_102]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_102]
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) [idea_rt.jar:na]
Caused by: java.lang.IllegalStateException: Either HibernateOperations or SessionFactory must be provided
    at org.springframework.util.Assert.state(Assert.java:392) ~[spring-core-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.batch.item.database.HibernateItemWriter.afterPropertiesSet(HibernateItemWriter.java:93) ~[spring-batch-infrastructure-3.0.7.RELEASE.jar:3.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    ... 20 common frames omitted

最佳答案

由于HibernateItemWriter是第三方依赖性,因此我认为将LCBOStoreWriter设置为@Bean而不是@Component并在其中设置sessionFactory可能更好。

从LCBOStoreWriter中删除@Component并将以下内容添加到BatchConfig

@Bean
public LCBOStoreWriter lCBOStoreWriter() {
    LCBOStoreWriter wr = new LCBOStoreWriter();
    wr.setSessionFactory(sessionFactory())
    return wr;
}


如果未自动接线,则可能需要设置lcboStoreService和dbConfigy。或者,您可以通过其他方式注入它们,我不记得所有的方式...

@Bean
public SessionFactory sessionFactory() throws SQLException {
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
    sessionFactory.setDataSource(dataSource());
    sessionFactory.setPackagesToScan(new String[] { "com.bytestree.model" });
    sessionFactory.setHibernateProperties(getHibernateProperties());
    return sessionFactory.getObject();
}

关于java - 配置自定义HibernateItemWriter时获取“必须提供HibernateOperations或SessionFactory”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43463249/

10-10 04:09