【问题标题】:Spring Data JPA does not work with String BatchSpring Data JPA 不适用于字符串批处理
【发布时间】:2016-10-27 09:44:09
【问题描述】:

我有这个数据库配置:

<beans ...
    <context:component-scan base-package="my.company"/>
    <context:annotation-config/>

    <tx:annotation-driven transaction-manager="transactionManager"/>
    <jpa:repositories base-package="my.company.repositories" entity-manager-factory-ref="emf"/>

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" scope="step">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
        <property name="url" value="#{jobParameters['DBurl']}"></property>
        <property name="username" value="#{jobParameters['DBuser']}"></property>
        <property name="password" value="#{jobParameters['DBpassword']}"></property>
    </bean>

    <bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="packagesToScan" value="my.company.entities"/>
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
        </property>
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
            </props>
        </property>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="emf"/>
    </bean>

    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

</beans>

在包my.company.repositories我已经定义了一个Jpa repo:

public interface UtilisateurRepository extends JpaRepository<Utilisateur, String> {
} 

然后我像这样使用它:

public final class PaymentAuthorizedUsersReader {
    @Autowired
    private UtilisateurRepository utilisateurRepository;

    public Set<User> retrieveUsers() {
        final List<Utilisateur> all = utilisateurRepository.findAll();

       .....
    }
}

但是,上下文初始化失败并出现以下错误:

[12:39:45][ClassPathXmlApplicationContext][WARN]Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.scopedTarget.emf': Scope 'step' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No context holder available for step scope
[12:39:45][CommandLineJobRunner][ERROR]Job Terminated in error: Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.scopedTarget.emf': Scope 'step' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No context holder available for step scope
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.scopedTarget.emf': Scope 'step' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No context holder available for step scope
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1583)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:732)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at org.springframework.batch.core.launch.support.CommandLineJobRunner.start(CommandLineJobRunner.java:290)
    at org.springframework.batch.core.launch.support.CommandLineJobRunner.main(CommandLineJobRunner.java:592)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.scopedTarget.emf': Scope 'step' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No context holder available for step scope
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:355)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:509)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:498)
    at org.springframework.context.support.AbstractApplicationContext.getBeansOfType(AbstractApplicationContext.java:1184)
    at org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors(BeanFactoryUtils.java:261)
    at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean.getMetamodels(JpaMetamodelMappingContextFactoryBean.java:85)
    at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean.createInstance(JpaMetamodelMappingContextFactoryBean.java:56)
    at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean.createInstance(JpaMetamodelMappingContextFactoryBean.java:26)
    at org.springframework.beans.factory.config.AbstractFactoryBean.afterPropertiesSet(AbstractFactoryBean.java:134)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1642)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1579)
    ... 13 more
Caused by: java.lang.IllegalStateException: No context holder available for step scope
    at org.springframework.batch.core.scope.StepScope.getContext(StepScope.java:167)
    at org.springframework.batch.core.scope.StepScope.get(StepScope.java:99)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:340)
    ... 24 more

这是spring-batchspring-data-jpa 之间已知的兼容性问题吗?

【问题讨论】:

  • 据我了解 SB 的经验,“步骤”范围不适用于 factorybean 创建的对象
  • @Luca Basso Ricci 我同意,我从emf 中删除了步骤范围,但正如我已经回复@Michael Minella,现在我收到另一个错误Error creating bean with name 'scopedTarget.scopedTarget.dataSource': Scope 'step' is not active for the current thread;。我需要dataSource bean 从命令行获取它的属性。

标签: java spring-batch spring-data-jpa


【解决方案1】:

您是实体经理 (emf),不能进行步进范围。这取决于您的事务管理器,这不是因此过早需要它。从您的实体管理器中删除步骤范围,它应该可以工作(无论如何,该 bean 的配置中都不需要它是步骤范围)。

【讨论】:

  • 我同意你的看法。但是,在从 emf 中删除 step 范围后,我收到另一个错误 Error creating bean with name 'scopedTarget.scopedTarget.dataSource': Scope 'step' is not active for the current thread; 。我需要将dataSource 设置为步进范围,因为它使用命令行参数。
  • 如果您使用的是 Spring Boot,您可以使用命令行参数而不使用作业参数。另一种方法是将该事务管理器设置为步骤范围并仅在该步骤中使用它。
  • 我确认使用 Spring Boot 可以正常工作。我想我会切换到 Spring Boot。这就是未来……
  • 顺便说一句,我注意到在使用 Spring boot 时,您不需要标记您的 bean @StepScoped 并提供 jobParameters。您只能使用@Value 来获取命令行参数。但是,如果您使用来自spring-batch-testJobLauncherTestUtils 以编程方式开始您的工作(就像在集成测试中一样),您仍然需要@StepScoped@Value("#{jobParameters['someParameter']}"
猜你喜欢
  • 2022-12-05
  • 1970-01-01
  • 2014-07-08
  • 2023-03-06
  • 2015-05-31
  • 1970-01-01
  • 2016-12-03
  • 2019-10-23
  • 2019-08-13
相关资源
最近更新 更多