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>
Related
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 ?
Consider I have something like this in beans.xml:
<bean id="emails" class="org.some.package.SomeClass">
<property name="emailList">
<list>
<value>pechorin#hero.org</value>
<value>raskolnikov#slums.org</value>
<value>stavrogin#gov.org</value>
<value>porfiry#gov.org</value>
</list>
</property>
</bean>
But I need to add emailList property into multiple beans. How can I do that without writing property to each bean? Can externalize property and inject it into each bean?
I expect something like:
<property name="commonProp">
<list>
<value>pechorin#hero.org</value>
<value>raskolnikov#slums.org</value>
<value>stavrogin#gov.org</value>
<value>porfiry#gov.org</value>
</list>
</property>
<bean id="emailsOne" class="org.some.package.ClassOne">
<property name="emailList" ref="commonProp" />
</bean>
<bean id="emailsTwo" class="org.some.package.ClassTwo">
<property name="emailList" ref="commonProp" />
</bean>
You can do it using: util:list
<util:list id="myList" value-type="java.lang.String">
<value>foo</value>
<value>bar</value>
</util:list>
Then use this myList reference in other beans.
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
I've configured in Spring listA (see below). It would be nice to have another one that contains all values from listA and expand it.
<bean id="listA" class="java.util.ArrayList">
<constructor-arg>
<list>
<value>a</value>
<value>b</value>
<value>...</value>
<value>z</value>
</list>
</constructor-arg>
</bean>
How to rewrite in Spring such Java code?
List listB = new ArrayList(listA);
listB.add("A");
...
listB.add("Z");
You can use collection merging:
<bean id="listA" class="java.util.ArrayList">
<constructor-arg index="0">
<list>
<value>a</value>
<value>b</value>
<value>...</value>
<value>z</value>
</list>
</constructor-arg>
</bean>
<bean id="listB" parent="listA">
<constructor-arg index="0">
<list merge="true">
<value>A</value>
<value>...</value>
<value>Z</value>
</list>
</constructor-arg>
</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.