I know this is a question which is asked quite often but my problem seems to be a little bit different.
Short introduction:
I have an DMLC which is polled against a queue.
After that the message is sent via DirectChannel to a chain.
Within the chain I use a unmarshalling-transformer (transform the incoming xml to interface-object).
Then again different steps (Validation etc., all via DirectChannel) and at the end of the flow I want to insert the (transformed) message into a database.
In the flow below there are different "error sources". For example the input message isn't proper and couldn't transformed (un-marshal) into an object. Or the database could not be achieved to insert the record.
Now the question concerning the different error types:
If the input message could not be transformed or the validation of the data generates an error, I want to send an error-message (or the exception) to the error-channel because it doesn't make sense to rollback the message.
If the database-insert fails (maybe due to a "system hang") I want to rollback the message to the input queue (peInputQueue).
Enclosed a snipplet from the config-xml:
<jms:message-driven-channel-adapter id="peMessageDrivenAdapter"
channel="jmsHeaderEnricherChannel"
acknowledge="transacted"
connection-factory="jmsTransactionConnectionFactory"
concurrent-consumers="1"
max-concurrent-consumers="5"
max-messages-per-task="5"
receive-timeout="500"
auto-startup="true"
destination="peInputQueue" />
<int:chain id="jmsInputChain" input-channel="jmsHeaderEnricherChannel" output-channel="routerTransformChannel">
<int:header-enricher>
<int:priority value="#{T(de.axa.batch.ecmcm.cmab.util.CmabConstants).LOW_PRIO}"/>
<int:header name="countMessage" ref="counter" />
<int:header name="protocol" value="jms"/>
<int:header name="msgReceiveDate" expression="T(System).currentTimeMillis()" />
<int:error-channel ref="errorChannel"/>
</int:header-enricher>
<int-xml:unmarshalling-transformer id="jmsModelUnmarshallerTransformer" unmarshaller="jmsModelUnmarshaller"/>
</int:chain>
<int:header-value-router input-channel="routerTransformChannel" header-name="protocol">
<int:mapping value="jms" channel="jmsTransformToCoreChannel"/>
</int:header-value-router>
<int:transformer id="jmsToCoreTransformer" input-channel="jmsTransformToCoreChannel"
ref="cmabInboundQueueMapper" output-channel="validationChannel"/>
<int:service-activator input-channel="validationChannel"
output-channel="processChannel"
ref="validationBean" />
<int:service-activator input-channel="processChannel" ref="databaseProcess"/>
In the configuration above the message is rollbacked if per example "validationBean" throws an exception.
But this is not what I'm expected. I want to adjust the message into the error channel. Therefore I enhanced the header in the "header-enricher" (see chain-element) to an errorChannel.
In the "validationBean" I recognized the errorChannel within the MessageHeaders but unfortunately it doesn't work. Instead of this a rollback is initiated.
So how can I achieved (my) desired solution.
Any helps are really appreciated.
That error-channel header isn't reachable. Just because everything is in the same Thread, so, an exception is just thrown like it is with regular Java.
The exception gets caught in the ChannelPublishingJmsMessageListener.GatewayDelegate.
And since there is no error-channel according to your configuration it is re-thrown to the DefaultMessageListenerContainer to make rallback.
So, you should make an error-channel configuration on the <jms:message-driven-channel-adapter> and also you should add some ErrorHandler to sever the "rallback or not" logic.