Spring Batch - Erro Config XML job - Date - java

I have a procedure in sql waiting three parameters. The first 2 parameters are dates and last a cursor.
How do I configure the XML job Spring Batch
I tried so
<bean id="databaseItemReader" class="org.springframework.batch.item.database.StoredProcedureItemReader">
<property name="dataSource" ref="dataSource" />
<property name="procedureName" value="MyProcedureSQL" />
<property name="fetchSize" value="50" />
<property name="parameters">
<list>
<bean class="org.springframework.jdbc.core.SqlParameter">
<constructor-arg index="0" value="P_INICIO"/>
<constructor-arg index="1">
<util:constant static-field="java.sql.TYPES.Date"/>
</constructor-arg>
</bean>
<bean class="org.springframework.jdbc.core.SqlParameter">
<constructor-arg index="0" value="P_TERMINO"/>
<constructor-arg index="1">
<util:constant static-field="java.sql.TYPES.Date"/>
</constructor-arg>
</bean>
<bean class="org.springframework.jdbc.core.SqlParameter">
<constructor-arg index="0" value="P_RESULT"/>
<constructor-arg index="1">
<util:constant static-field="java.sql.Types.int"/>
</constructor-arg>
</bean>
</list>
</property>
<property name="rowMapper">
<bean class="main.java.br.com.util.DataEmployeeMapper" />
</property>
<property name="refCursorPosition" value="3"/>
<property name="preparedStatementSetter" ref="preparedStatementSetter" />
</bean>
It appears the error
Invocation of init method failed; nested exception is java.lang.NoSuchFieldException: Date
In this variation I have also tried
<util:constant static-field="java.sql.Date"/>
<util:constant static-field="java.sql.Types.timeStamp"/>
How do I set to send the two dates for procedure?

It may help to change use argument names instead of 'index' in the constructor-arg element, to debug this. e.g. change
<constructor-arg index="1">
<util:constant static-field="java.sql.TYPES.Date"/>
</constructor-arg>
to this
<constructor-arg name="sqlType">
<util:constant static-field="java.sql.TYPES.Date"/>
</constructor-arg>
I suspect you there may be some ambiguity around what constructor is called and how the argument types are interpreted

Related

Chain a JdbcCursorItemReader and a StoredProcedureItemReader in the same Sprin Batch step

I want to chain two readers : JdbcCursorItemReader and a StoredProcedureItemReader. The result of the first reader will be passed as parameters to the stored procedure, the results of this stored procedure will then be passed to some writer.
My two readers will be somthing like this :
<bean id="centralItemReader"
class="org.springframework.batch.item.database.JdbcCursorItemReader"
scope="step">
<property name="dataSource" ref="DS" />
<property name="sql">
<value>
<![CDATA[
select num1, num2
from table1
]]>
</value>
</property>
<property name="rowMapper">
<bean class="batch.model.PubRowMapper" />
</property>
</bean>
<bean id="publishProcedureReader"
class="org.springframework.batch.item.database.StoredProcedureItemReader"
scope="step">
<property name="dataSource" ref="DS" />
<property name="procedureName" value="PUBLISH"/>
<property name="parameters">
<list>
<bean class="org.springframework.jdbc.core.SqlParameter">
<!-- first parameter from the previous reader result -->
<constructor-arg index="0" value="value_here"/>
<constructor-arg index="1">
<util:constant static-field="java.sql.Types.INTEGER"/>
</constructor-arg>
</bean>
<bean class="org.springframework.jdbc.core.SqlParameter">
<!-- Second parameter from the previous reader result -->
<constructor-arg index="0" value="value_here"/>
<constructor-arg index="1">
<util:constant static-field="java.sql.Types.INTEGER"/>
</constructor-arg>
</bean>
</list>
</property>
<property name="rowMapper">
<bean class="batch.model.ProcedureRowMapper" />
</property>
</bean>
How can I pass the results from the first reader to the second one ?
In my understanding a spring batch step contains only one reader, one processor, and one writer
Is there some way to chain these two readers as a composite reader in the same step ?

How to create and config an inner builder class with spring

I am trying to springify the following code snippet:
MongoClient mongoClient = new MongoClient("127.0.0.1", 27017);
DB db = mongoClient.getDB("jcr");
DocumentNodeStore ns = new DocumentMK.Builder().setMongoDB(db)
.getNodeStore();
Repository repo = new Jcr(new Oak(ns)).createRepository();
taken from Oak website : http://jackrabbit.apache.org/oak/docs/construct.html
The problem line is:
DocumentNodeStore ns = new DocumentMK.Builder().setMongoDB(db)
.getNodeStore();
Here is how I have configured it within the xml:
<bean id="builder" class="org.apache.jackrabbit.oak.plugins.document.DocumentMK$Builder">
</bean>
<bean factory-bean="builder" factory-method="setMongoDB" >
<constructor-arg name="db" value="#{mongoDbTags.getDb()}"/>
</bean>
I have configured a SimpleMongoDbFactory and obtaining the db to be injected into the builder bean calling the setMethod via factory method.
Please note this does not exist as an attribute under the builder Class but the method does exist.
here is my config file:
<bean id="mongo" class="com.mongodb.MongoClient">
<constructor-arg name="host" value="localhost" />
<constructor-arg name="port" value="27017" />
</bean>
<bean id="mongoDbTags" class="org.springframework.data.mongodb.core.SimpleMongoDbFactory">
<constructor-arg name="mongo" ref="mongo" />
<constructor-arg name="databaseName" value="jcr111" />
</bean>
<bean id="builder" class="org.apache.jackrabbit.oak.plugins.document.DocumentMK$Builder">
</bean>
<bean factory-bean="builder" factory-method="setMongoDB" >
<constructor-arg name="db" value="#{mongoDbTags.getDb()}"/>
</bean>
<bean id="documentMK" class="org.apache.jackrabbit.oak.plugins.document.DocumentMK">
<constructor-arg name="builder" ref="builder" />
</bean>
<bean id="oak" class="org.apache.jackrabbit.oak.Oak">
<constructor-arg name="store" value="#{builder.getNodeStore()}" />
</bean>
<bean id="jcr" class="org.apache.jackrabbit.oak.jcr.Jcr">
<constructor-arg name="oak" ref="oak" />
</bean>
<bean id="jcrSessionFactory"
class="org.springframework.extensions.jcr.JcrSessionFactory">
<property name="repository" value="#{jcr.createRepository()}" />
<property name="credentials">
<bean class="javax.jcr.SimpleCredentials">
<constructor-arg index="0" value="admin" />
<constructor-arg index="1" value="admin" />
</bean>
</property>
</bean>
<bean id="jcrTemplate" class="org.springframework.extensions.jcr.JcrTemplate">
<property name="sessionFactory" ref="jcrSessionFactory" />
<property name="allowCreate" value="true" />
</bean>
For others that get stuck in this I simply created a wrapper class which called the builder from within it's constructor

Java Spring IOC constructor-arg inject a List<Integer>

i am trying to develop a Spring bean like this
<bean id="id" class="java.util.ArrayList" scope='prototype'>
<constructor-arg>
<list>
<bean class='MyClass'>
<property name='id' value='1313'/>
<property name="name" value='John Lennon'/>
<property name='wifes'>
<list>
<bean class="WifeClazz">
<constructor-arg index='0' value='Cynthia Lennon'/>
<constructor-arg index='1'>
<list><value>1962</value><value>1968</value></list>
</constructor-arg>
</bean>
</list>
</property>
</bean>
</list>
</constructor-arg>
</bean>
this is just a example the WifeClazz the name is just for the example.. have a Constructor which have a String and a series of Integers.. like this example
new WifeClazz("Cinthia Lennon",java.util.Arrays.asList(1,2,3,4,5,6,7,8));
the integers may be a severals from 1 to 10 integers.
but i think is kind of annoying do something like this
<constructor-arg index='1'>
<list>
<value>1</value>
<value>2</value>
<value>3</value>
<value>4</value>
</list>
</constructor-arg>
would be great if i could do something like this
<constructor-arg index='1'>
<value>#{T(java.util.Arrays).asList(1,2,3,4)}</value>
</constructor-arg>
but throws Exception any clue?
any help is hugely appreciate.
UPDATE
I have change my code according Edwin a something like this.
<constructor-arg index="1" type="java.util.Collection" value="#{T(java.util.Arrays).asList(1,2,3,4,5)}"/>
but throws
Caused by: java.lang.IllegalArgumentException: Final expected argument should be array type (the varargs parameter)
my target clazz is
public MyClass(final String name,final List<Integer>years){}
my resulting code
<bean id="id" class="java.util.ArrayList" scope='prototype'>
<constructor-arg>
<list>
<bean class='MyClass'>
<property name='id' value='1313'/>
<property name="name" value='John Lennon'/>
<property name='wifes'>
<list>
<bean class="WifeClazz">
<constructor-arg index='0' value='Cynthia Lennon'/>
<constructor-arg index="1" type="java.util.Collection" value="#{T(java.util.Arrays).asList(1,2,3,4,5)}"/>
</bean>
</list>
</property>
</bean>
</list>
</constructor-arg>
</bean>
this solves the trick...
<constructor-arg index='1' type="java.util.List" value="#{{1,2,3,4,5}}"/>
This works for me
<bean id="list" class="java.util.ArrayList">
<constructor-arg index="0" value="#{T(java.util.Arrays).asList(1,2,3,4,5)}"/>
</bean>
To disambiguate constructors, this also works for me
<bean id="list" class="java.util.ArrayList">
<constructor-arg type="java.util.Collection" value="#{T(java.util.Arrays).asList(1,2,3,4,5)}"/>
</bean>
You can also use a collection SPeL, like this, and avoid having to use Arrays.asList directly.
<bean id="list" class="java.util.ArrayList">
<constructor-arg type="java.util.Collection" value="#{{1,2,3,4,5}}"/>
</bean>

ReloadingPropertyPlaceholderConfigurer

For some reason the ReloadablePropertiesFactoryBean doens't seem to do what I expect. When I change a property in the test.properties file I get a log message saying:
9979 [timer] INFO com.krest.core.properties.ReloadablePropertiesFactoryBean - Reloading Properties...
But for some reason nothing happens. The old property value is still set on my test bean. Does anybody know why this is? I use Spring 3 and my configuration looks like this:
<bean id="configproperties"
class="com.krest.core.properties.ReloadablePropertiesFactoryBean">
<property name="location"
value="classpath:test.properties" />
</bean>
<bean id="propertyConfigurer"
class="com.krest.core.properties.ReloadingPropertyPlaceholderConfigurer">
<property name="properties" ref="configproperties" />
<property name="reloadingPlaceholderPrefix" value="rel{" />
<property name="reloadingPlaceholderSuffix" value="}" />
</bean>
<bean id="mybean" class="nl.mycompany.TestBean">
<property name="message" value="rel{timer-delay}" />
</bean>
<!-- regularly reload property files. -->
<bean id="timer" class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<bean id="reloadProperties"
class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="period" value="1000" />
<property name="runnable">
<bean class="com.krest.core.properties.ReloadConfiguration">
<property name="reconfigurableBeans">
<list>
<ref bean="configproperties" />
</list>
</property>
</bean>
</property>
</bean>
</property>
</bean>

method-invoking Spring bean

I've declared the following bean in my Spring config
<bean id="templateCacheClearingTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="delay" value="5000" />
<property name="period" value="5000" />
<property name="timerTask">
<bean class="org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean">
<property name="targetObject" ref="templateMailService" />
<property name="targetMethod" value="clearCache" />
</bean>
</property>
</bean>
This should cause the clearCache() method of the templateMailService bean to be invoked every 5000ms, but nothing appears to be happening. Am I missing something?
Cheers,
Don
I think you need:
<bean id="timerFactory" class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<ref bean="templateCacheClearingTask"/>
</list>
</property>
</bean>
In addition to what you already have.

Categories