Results 1 to 10 of 10

Thread: LateBinding DataSource

  1. #1
    Join Date
    Mar 2009
    Posts
    18

    Default 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. #2
    Join Date
    Feb 2008
    Posts
    488

    Default

    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.

  3. #3
    Join Date
    Mar 2009
    Posts
    18

    Default 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!

  4. #4
    Join Date
    Feb 2008
    Posts
    488

    Default

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

  5. #5
    Join Date
    Mar 2009
    Posts
    18

    Default

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

  6. #6
    Join Date
    Feb 2008
    Posts
    488

    Default

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

  7. #7
    Join Date
    Mar 2009
    Posts
    18

    Thumbs up

    thank you - should be possible to do it that way

  8. #8

    Default Same problem

    Hi,

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

    Can you share you config file?

    Thanks,
    Karan

  9. #9
    Join Date
    Mar 2009
    Posts
    18

    Default

    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

  10. #10

    Default

    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 ....

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •