Spring HashMap value-ref Key points to value ref name - spring

Here is my HashMap in spring context which uses value-ref :
<util:map id="generalDAOMap" map-class="java.util.HashMap">
<entry key="1" value-ref="userDAO" />
<entry key="2" value-ref="accountsDAO" />
<entry key="3" value-ref="settingsDAO" />
</util:map>
<bean id="userDAO"
class="com.test.myproj.dao.impl.UserDAOImpl" />
<bean id="accountsDAO"
class="com.test.myproj.dao.impl.AccountsDAOImpl" />
<bean id="settingsDAO"
class="com.test.myproj.dao.impl.SettingsDAOImpl" />
In my Java class i have autowired the "generalDAOMap" as below:
#AutoWired
private Map<String,GeneralDAO> generalDAOMap;
//getters and setters follows
When i print the map value its as follows :
{userDAO = com.test.myproj.dao.impl.UserDAOImpl#164d6ae,accountsDAO = com.test.myproj.dao.impl.AccountsDAOImpl#ed9382 , settingsDAO = com.test.myproj.dao.impl.SettingsDAOImpl#ed9586}
but the Key values should be "1","2" and "3" , why its getting replaced as "userDAO ","settingsDAO " and "accountsDAO ", due to which when i use getGeneralDAOMap.get("1") it returns null. Kindly help.

Can you try using #Resource instead of using #Autowired ?
Spring docs says this,
As a specific consequence of this semantic difference, beans that are themselves defined as a collection or map type cannot be injected through #Autowired, because type matching is not properly applicable to them. Use #Resource for such beans, referring to the specific collection or map bean by unique name.

you can try ...
<util:map id="generalDAOMap" map-class="java.util.HashMap">
<entry key="1">
<bean class="com.test.myproj.dao.impl.UserDAOImpl" />
</entry>
<entry key="2">
<bean class="com.test.myproj.dao.impl.AccountsDAOImpl" />
</entry>
<entry key="3">
<bean class="com.test.myproj.dao.impl.SettingsDAOImpl" />
</entry>
</util:map>

Related

Spring batch JdbcPaging Item Reader with multiple table joins

Need to implement paginating for an spring batch application. The Query has multiple join, Guide for an effective Pagining query, with existing table model can this join be effectively written to pagination where "ED_EMP_LOGIN_STATE" is the filter where other tables are select. running this query is still slow and look likes paginzation with rownnum condition does not show any impact on execution plan.
How this query can be modified to pass in spring batch paginzation reader
<bean id="empItemReader" class="org.springframework.batch.item.database.JdbcPagingItemReader" scope="step">
<property name="dataSource" ref="empDataSource" />
<property name="rowMapper">
<bean class="org.sample.model.EmployeeMapper" />
</property>
<property name="queryProvider">
<bean class="org.springframework.batch.item.database.support.SqlPagingQueryProviderFactoryBean">
<property name="dataSource" ref="empDataSource" />
<property name="sortKeys">
<map>
<entry key="ID" value="ASCENDING"/>
</map>
</property>
<!-- Intentionally put sort key second in the query list as a test -->
<property name="selectClause" >
<value>
<![CDATA[
emp_task_sub_details.DEP_NAME AS DEP_NAME
,emp_task_sub_details.EmpName AS EmpName
,emp_task_sub_details.EmpFirstName AS EmpFirstName
,emp_task_sub_details.EmpIDCard AS EmpIDCard
,emp_task_sub_details.EmpBuilding AS EmpBuilding
,emp_task_sub_details.EmpLocation EmpLocation ENV_CAT
,emp_task_sub_details.NAME AS NAME
,ed_parent_join.task_name AS TASK_NAME
,ed_parent_join.start_time AS TASK_NAME_START_TIME
,ed_parent_join.finish_time AS TASK_NAME_END_TIME
,emp_task_sub_details.STATUS AS STATUS
,emp_task_sub_details.STATE_ID AS ID
]]>
</value>
</property>
<property name="fromClause">
<value>
<![CDATA[
ED_EMP_LOGIN_STATE ed_parent_join
JOIN (
select
ed_dep.name as DEP_NAME
,empName_code_prop.string as EmpName
,empfirst_code_prop.string as EmpFirstName
,id_code_prop.string as EmpIDCard
,build_code_prop.string as EmpBuilding
,loc_code_prop.string as EmpLocation
,ed_emp.name as NAME
,ed_emp_lg_st.id as STATE_ID
,ed_emp_tas_wk.STATUS AS STATUS
from
ED_DEPARTMENT ed_dep
,ED_EMPLOYEE ed_emp
,ed_emp_tas_wkK ed_emp_tsk
,ED_EMP_LOGIN ed_emp_lg
,ED_EMP_LOGIN_STATE ed_emp_lg_st
,ED_EMP_LOGIN_WORK ed_emp_tas_wk
,ED_TASK_PROPS empName_code_prop
,ED_TASK_PROPS empfirst_code_prop
,ED_TASK_PROPS id_code_prop
,ED_TASK_PROPS build_code_prop
,ED_TASK_PROPS loc_code_prop
,ED_ACTIVITY ed_act
,ED_LOCATION ed_loc
where
ed_emp.id = ed_dep.id
and ed_emp.tsk_id = ed_emp_tsk.id
and ed_emp_lg.tsk_id = ed_emp_tsk.id
and ed_emp_lg_st.parent_emp_id = ed_emp_lg.id
and ed_emp_tas_wk.state_id = ed_emp_lg_st.id
and ed_emp_lg.prop_id = empName_code_prop.parent_prop_id
and empName_code_prop.name = 'EmpName'
and ed_emp_lg.prop_id = empfirst_code_prop.parent_prop_id
and empfirst_code_prop.name = 'EmpFirstName'
and ed_emp_lg.prop_id = id_code_prop.parent_prop_id
and id_code_prop.name = 'EmpIDCard'
and ed_emp_lg.prop_id = build_code_prop.parent_prop_id
and build_code_prop.name = 'EmpBuilding'
and ed_emp_tas_wk.JOB_ID = ed_act.id
and ed_act.environment_name = ed_loc.name
and ed_loc.prop_id = loc_code_prop.parent_prop_id
and loc_code_prop.name = 'EmpLocation') emp_task_sub_details
ON emp_task_sub_details.STATE_ID = ed_parent_join.id
]]>
</value>
</property>
<property name="whereClause">
<value>
<![CDATA[
ed_parent_join.start_time >= :startTime
and ed_parent_join.finish_time < :finishTime
]]>
</value>
</property>
</bean>
</property>
<property name="pageSize" value="${loadPageCommitSize}" />
<property name="parameterValues">
<map>
<entry key="startTime" value="#{jobParameters[StartTime]}" />
<entry key="finishTime" value="#{jobParameters[FinishTime]}" />
</map>
</property>
</bean>

Spring Integration: How to get value from util:map into SI's Router

My configuration is like below:
I am using SpEL inside router to get values from map.
<util:map id="routeConfig">
<entry key="Default" value="not configured" />
<entry key="GB22XXX" value="LON" />
<entry key="AEADXXX" value="ME" />
<entry key="HBXXXX" value="ME" />
<entry key="EBHBXBAO" value="ME" />
</util:map>
<router input-channel="InputRoutingChannel" default-output-channel="testOutputChannel" expression="#routeConfig.get('payload.getMsgHeader().getSourceSystem().substring(4, 12)')">
<mapping value="LON" channel="MarshallerOutputChannel_lonme" />
<mapping value="ME" channel="MarshallerOutputChannel_me" />
</router>
Your issue is here:
expression="#routeConfig.get('payload.getMsgHeader().getSourceSystem().substring(4, 12)')
Since you get deal with runtime Message you really don't need to wrap to the literal. Hence an answer to you is:
expression="#routeConfig.get(payload.msgHeader.sourceSystem.substring(4, 12))

Transforming HL7 v2 to XML using apache camel routes

I am new to HL7 .I have to convert the HL7v2 to XML using apache camel routes.I am extracting the HL7 message from file.
Can any one help me how to convert HL7 to XML
There is an HL7 component for unmarshalling the file into a HAPI message. The HAPI api also includes an XMLParser that will convert the message into xml. So you should be able to combine the two into a simple camel route like the following:
<bean id="hl7XmlConverter" class="example.Hl7XmlConverter" />
<bean id="hl7FileFilter"
class="org.apache.camel.component.file.AntPathMatcherGenericFileFilter">
<property name="includes" value="*.hl7" />
</bean>
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route id="hl7FileRoute">
<from
uri="file:///tmp/test/?delete=true&moveFailed=.error&filter=#hl7FileFilter" />
<convertBodyTo type="java.lang.String" />
<log message="HL7 Request: ${body}" />
<unmarshal>
<hl7 validate="true" />
</unmarshal>
<bean ref="hl7XmlConverter"/>
<log message="HL7 Response: ${body}" />
</route>
</camelContext>
Where the bean is just a simple method:
public String convertMessage(Message message) throws HL7Exception{
XMLParser parser = new DefaultXMLParser();
return parser.encode(message);
}
Depending on your desired xml format, you could also add an xslt after the bean.

Add entry to dictionary in child object

How is it possible to add entry to dictionary, defined in parent object, from the child object?
*UPDATED
I edit my config as follows:
<object id="ParentType" singleton="false" type="SomeType">
<property name="FieldNameMap">
<dictionary key-type="string" value-type="string" >
<entry key="Title" value="TitleName"/>
</dictionary>
</property>
</object>
<object id="ChildType" singleton="false" type="SomeType" parent="ParentType">
<property name="FieldNameMap">
<dictionary merge="true">
<!-- this entry should be added to, not replace the whole Dictionary -->
<entry key="Position" value="PositionName"/>
</dictionary>
</property>
</object>
but, unfortunately, it now throws cast exception:
Cannot convert property value of type
[System.Collections.Specialized.HybridDictionary] to required type
[System.Collections.Generic.IDictionary`2[[System.String,
],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089]]
I haven't tried this myself, but according to the docs, spring.net will use the Add method of the collection to add items, if the collection itself is exposed as a readonly property.
So it might be possible to use object definition inheritance to achieve the behavior you describe. Config will be something like:
<object id="ParentType" singleton="false" type="SomeType"
abstract="true">
<property name="FieldNameMap">
<dictionary>
<entry key="Title" value="TitleName"/>
</dictionary>
</property>
</object>
<object id="ChildType" singleton="false" type="SomeType"
parent="ParentType">
<property name="FieldNameMap">
<dictionary>
<!-- this entry should be added to, not replace the whole Dictionary -->
<entry key="Position" value="PositionName"/>
</dictionary>
</property>
</object>
This will only work if FieldNameMap is a readonly property.

How to pass Mule expression to spring property

I'm looking for a way to assign an exception message to spring property at runtime in mule flow (Mule 3.3.0)
This is how my code-snippet looks like:
<catch-exception-strategy>
<logger message="----->Exception is #[exception.causeException]"
level="INFO" />
<custom-transformer
class="com.company.transformer.VelocityMessageTransformer">
<spring:property name="velocityEngine" ref="velocityEngine" />
<spring:property name="templateName" value="soap11Fault.vm" />
<spring:property name="beanClass">
<spring:bean parent="abstractSoap11ClientFault">
<spring:property name="faultString" value="Invalid Request" />
<spring:property name="detail" value="${exception.causeException}" />
</spring:bean>
</spring:property>
</custom-transformer>
</catch-exception-strategy>
I want to assign exception cause to detail property here:
<spring:property name="detail" value="${exception.causeException}" />
but spring is looking for this property in properties file. I tried doing this also
<spring:property name="detail" value="${#[exception.causeException]}" /> but doesn't work.
Is there a way to pass Mule expression at run-time to Spring property?
Properties are set during the application initialization: the value you want to pass is evaluated at runtime, so that can't work.
What you need to do is make com.company.transformer.VelocityMessageTransformer extend org.mule.transformer.AbstractMessageTransformer. You will then have to override transformMessage(MuleMessage message, String outputEncoding), which will give you access to the current message and its associated exception payload. The exception payload is what you get with the #[exception] expression.

Resources