0
votes

Please see link :

Spring Integration: Inbound-channel-adapter update query parameter exception when using RowMapper

I am doing similar config, but not sure how to use row-mapper with splitter.

I am trying to create a db-poller and expecting to receive incoming rows in service-activator using row-mapper, but messages are not reaching there..

Here is my configuration. Please advise.

My config:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:task="http://www.springframework.org/schema/task" 
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:int="http://www.springframework.org/schema/integration"
    xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc" 
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc-3.0.xsd">

    <context:component-scan base-package="com.checkfree.isolutions" />

    <int-jdbc:inbound-channel-adapter id="invoiceInbound" query="select * from invoice where status = '0'" auto-startup="true"
      channel="invoiceInboundChannel" data-source="dataSource" row-mapper="rowMapper"
      update="update invoice set status = 'PROCESSED' where id in (:id) " max-rows-per-poll="1">
        <int:poller max-messages-per-poll="1" fixed-rate="10000">
        <int:transactional transaction-manager="transactionManager" 
                isolation="DEFAULT"
                propagation="REQUIRED" 
                read-only="false" 
                timeout="1000"/>
        </int:poller>
    </int-jdbc:inbound-channel-adapter>

    <!-- Add RowMapper tag : row-mapper="rowMapper" -->

    <bean id="rowMapper" class="com.checkfree.isolutions.InvoiceMapper"></bean>

    <int:chain input-channel="invoiceInboundChannel" output-channel="filteredChannel">
            <int:splitter ref="invoiceSplitter" />
    </int:chain>

    <int:channel id="filteredChannel" />    

    <int:service-activator id="taskActivator" input-channel="filteredChannel" ref="taskCreator"  method="processInvoice">
    </int:service-activator>


</beans>

Here is my service activator :

@Component("taskCreator")
public class TaskCreator {

    static Logger logger = Logger.getLogger(TaskCreator.class.getName());

    @Autowired
    InvoiceService invoiceService;

    @Transactional(readOnly = false)
    public void processInvoice(Object invoiceObj) throws Exception {
        System.out.println("row received.." + invoiceObj.getClass().getCanonicalName());
    }
}

I am not able to see print message "row received.." in console.

But in debug rowmapper's is mapRow method is getting called with each invocation.

public class InvoiceMapper implements RowMapper {

    @Override
    public Invoice mapRow(ResultSet rs, int rowNum) throws SQLException {

        Invoice invoice = new Invoice();
         --
         --
    }
}

What I trying to achieve is that my TaskCreator should receive incoming table row in row-mapper (InvoiceMapper) format.

I just corrected my config.

When I switch on debug I can see control going to RowMapper.

Question: I dont know how to use row-mapper with spiltter. can anybody give any example..

Can you please advise. Thanks in advance..

Regards, Shiv

3
What does invoiceSplitter look like? Turn on DEBUG logging and follow the messages through the channels (preSend, postSend).Gary Russell
Gary, Thanks for response. I have corrected my configuration. I can receive messages using invoicesplitter (If I remove row-mapper attribute). when I add row-mapper attribute then processInvoice doesn't get called. In debug mode I can see control going to row-mapper class, but control never goes to TastCreate (service-activator) class. So If I minus row-mapper entry then My code work very well. But when I add row-mapper which I need for some JDBC specific conversions. then control never goes to service activator class.Shivnarayan

3 Answers

0
votes

You have here two issues:

  1. There is no reason to use <splitter>, if you expect only one row - max-rows-per-poll="1"

  2. You have two subscribers for invoiceInboundChannel - <chain> with <splitter> and <service-activator>. It works, but not as you expect, because of RoundRobinLoadBalancingStrategy

So, maybe your goal is to have filteredChannel as an input for <service-activator> ?

0
votes

i assume that your 'invoiceInboundChannel' channel is a DirectChannel which by definition invokes a single subscriber for each sent Message.

you have configured more than one subscribers (chain and service activator) to that channel. that is why you are facing this issue.

here is the solution. change the input-channel of service-activator to filteredChannel:

<int:service-activator id="taskActivator" input-channel="filteredChannel" ref="taskCreator"  method="processInvoice">
</int:service-activator>

hopefully you will receive the splited messages as per your splitter (invoiceSplitter) implementation into your service activator (taskActivator).

0
votes

Thanks my problem was solved.

Issue was not the configuration. But issue is that I in original invoice table got primary key as RAW type (encrypted format) whereas my Invoice Class was showing same field as Long. So while running update I was getting "ORA-00932: inconsistent datatypes: expected BINARY got NUMBER". But after debug I could figure out this.

Thanks all for your help.