Announcement Announcement Module
Collapse
No announcement yet.
LateBinding DataSource Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • LateBinding DataSource

    Hi everyone,

    I use the actual release 2.0.1 of spring batch.

    One job parameter is the user (and password) of the db-connection to use.
    I thought of the new feature of late binding the parameter to the datasource:

    Code:
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" scope="step">
    		<property name="driverClassName" value="${jdbc.driverClassName}" />
    		<property name="url" value="${jdbc.url}" />
    		<property name="username" value="#{jobParameters[userId]}" />
    		<property name="password" value="#{jobParameters[password]}" />
    	</bean>
    
    	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" lazy-init="true" >
    		<property name="dataSource" ref="dataSource" />
    	</bean>

    But this ends in an illegalargumentexception for DataSourceTransactionManager:

    Code:
    Job Terminated in error:
    java.lang.IllegalArgumentException: Bean object must not be null
    	at org.springframework.util.Assert.notNull(Assert.java:112)
    	at org.springframework.beans.BeanWrapperImpl.setWrappedInstance(BeanWrapperImpl.java:193)
    	at org.springframework.beans.BeanWrapperImpl.setWrappedInstance(BeanWrapperImpl.java:182)
    	at org.springframework.beans.BeanWrapperImpl.<init>(BeanWrapperImpl.java:135)
    	at org.springframework.batch.core.scope.util.PlaceholderTargetSource.getPropertyFromContext(PlaceholderTargetSource.java:291)
    	at org.springframework.batch.core.scope.util.PlaceholderTargetSource.convertFromContext(PlaceholderTargetSource.java:283)
    	at org.springframework.batch.core.scope.util.PlaceholderTargetSource.replaceIfTypeMatches(PlaceholderTargetSource.java:344)
    	at org.springframework.batch.core.scope.util.PlaceholderTargetSource.access$400(PlaceholderTargetSource.java:55)
    	at org.springframework.batch.core.scope.util.PlaceholderTargetSource$2.resolveStringValue(PlaceholderTargetSource.java:179)
    	at org.springframework.beans.factory.config.BeanDefinitionVisitor.resolveStringValue(BeanDefinitionVisitor.java:265)
    	at org.springframework.batch.core.scope.util.PlaceholderTargetSource$3.resolveValue(PlaceholderTargetSource.java:190)
    	at org.springframework.beans.factory.config.BeanDefinitionVisitor.visitPropertyValues(BeanDefinitionVisitor.java:142)
    	at org.springframework.beans.factory.config.BeanDefinitionVisitor.visitBeanDefinition(BeanDefinitionVisitor.java:82)
    	at org.springframework.batch.core.scope.util.PlaceholderTargetSource.getTarget(PlaceholderTargetSource.java:204)
    	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:184)
    	at $Proxy0.getConnection(Unknown Source)
    	at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:200)
    	at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:377)
    	at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:263)
    	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:101)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    	at $Proxy3.getLastJobExecution(Unknown Source)
    	at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:85)
    	at org.springframework.batch.core.launch.support.CommandLineJobRunner.start(CommandLineJobRunner.java:207)
    	at org.springframework.batch.core.launch.support.CommandLineJobRunner.main(CommandLineJobRunner.java:254)
    scope="step" follows this:

    Code:
    Job Terminated in error:
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'lazyBindingProxy.transactionManager#sysinit': 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
    other beans with scope="step" are ok (trxMgr gets a second dummy datasource):

    Code:
    <bean id="errorDao" class="xxx.xxx.JdbcErrorDao" scope="step">
    		<property name="dataSource" ref="dataSource" />
    Namespace declaration with spring-batch...

    Any help?

    Thanks a lot...

  • #2
    I think that you're problem arises from the fact that the data source is used outside the context of a step (ie, by the job), so it doesn't make sense to step-scope it.

    Comment


    • #3
      don't need step-scope it for lateBinding

      Hi,

      I need to step-scope it for lateBinding.

      Code:
      <property name="username" value="#{jobParameters[userId]}" />
      <property name="password" value="#{jobParameters[password]}" />
      Or is there another possible scope? Or another possibilty?

      Thanks a lot!

      Comment


      • #4
        You should probably put your datasource information in a properties file and use the "${userId}" syntax instead.

        Comment


        • #5
          Requirement is, that the user and password are job parameters, because they are different each time

          Comment


          • #6
            You could use VM Args. Giving "-DuserId=whatever" from the command line will allow you to use "${userId}" in your application context.

            Comment


            • #7
              thank you - should be possible to do it that way

              Comment


              • #8
                Same problem

                Hi,

                could you please elaborate as to "what exactly did you do?"

                Can you share you config file?

                Thanks,
                Karan

                Comment


                • #9
                  heres the relevant part of my config:

                  Code:
                  <beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
                  		<beans:property name="driverClassName" value="${jdbc.driverClassName}" />
                  		<beans:property name="url" value="${jdbc.url}" />
                  		<beans:property name="username" value="${username}" /> <!--  -D... -->
                  		<beans:property name="password" value="${password}" /> <!--  -D... -->
                  	</beans:bean>

                  programm start:

                  Code:
                  java -Dusername=DB_USER_NAME -Dpassword=DB_PASSWORD -jar boXmlFxxx.jar jobs\boToXMLJob.xml boToXMLJob
                  hope, that helps

                  Comment


                  • #10
                    you can also have a look to the spring batch samples and the SystemPropertyInitializer. It allows you to pick a different configuration file based on a system property and it set a default one if the property is not set. This is used in the samples to switch from one database vendor to another.

                    You could store your different environments in such a file and use a property placeholder. That way, all you would have to do is

                    java -Denv=myEnv ....

                    Comment

                    Working...
                    X