This forum is now a read-only archive. All commenting, posting, registration services have been turned off. Those needing community support and/or wanting to ask questions should refer to the Tag/Forum map, and to http://spring.io/questions for a curated list of stackoverflow tags that Pivotal engineers, and the community, monitor.

More notes on JDBC-AMQP

Jul 2nd, 2013, 06:57 AM

I have an message flow that reads rows from a db via jdbc outbound gateway, splits the rows and sends each row, as a message, to an amqp outbound adapter. I have descibed this flow in other recent posts to this forum. Another application (also running SI) reads the message from the queue, and get this error:

Normally, messages on this queue are type LinkedHashMap (which is how they are created byt the original sender) and this flow works fine. Seems like JDBC gateway produces a LinkedCaseInsensitiveMap on the republish. Is this is a bug/feature?

What is the workaround? I was thinking a transformer in the republish flow on the sending end.

Whenever you ask these questions, please show the relevant configuration - in this case from the inbound adapter to the transformer; it will save us, and you, time because then we don't have to speculate about what you have.

<speculation>

My best guess is that you are using the default message converter (SimpleMessageConverter) in the outbound and inbound adapters. This means that, for Serializable payloads, the adapter will use Java serialization and set the contentType header to "application/x-java-serialized-object".

This header is understood by the inbound converter (in the adapter) and the Map is deserialized for you - you don't need a PayloadDeserializingTransformer.

I am guessing your "other" application is not setting the content type, so the adapter doesn't know what to do with it so gives you a byte[] - hence you need the transformer.

Solutions:

1. Set the contentType header in all producing applications and remove the transformer.
2. Add a payload type router and only route through the transformer if the payload is a byte[] (skip the transformer if the payload is already a Map).

</speculation>

Comment

Whenever you ask these questions, please show the relevant configuration - in this case from the inbound adapter to the transformer; it will save us, and you, time because then we don't have to speculate about what you have.

<speculation>

My best guess is that you are using the default message converter (SimpleMessageConverter) in the outbound and inbound adapters. This means that, for Serializable payloads, the adapter will use Java serialization and set the contentType header to "application/x-java-serialized-object".

This header is understood by the inbound converter (in the adapter) and the Map is deserialized for you - you don't need a PayloadDeserializingTransformer.

I am guessing your "other" application is not setting the content type, so the adapter doesn't know what to do with it so gives you a byte[] - hence you need the transformer.

Solutions:

1. Set the contentType header in all producing applications and remove the transformer.
2. Add a payload type router and only route through the transformer if the payload is a byte[] (skip the transformer if the payload is already a Map).

</speculation>

Gary, thank you for parsing my post and making the correct speculation. We fixed it with option 1. I was not aware that this content type existed. That's really cool. Passing serialized Java Objects around in messaging. The more I learn about SI and Rabbit the more I realize this is likely the best system I have ever seen for middleware programming. Good job guys!

Comment

Just one caveat - passing around java serialized objects is generally not the "AMQP way" of doing things because of its polyglot nature. You are stuck with using Java in the producer(s) and consumer(s). It works, but you might (perhaps in future) want to consider using a language-neutral serialization technique (such as JSON). Spring-AMQP provides a JsonMessageConverter for this purpose. It sets some additiona headers that contain type information, to help the deserialization but that should not be necessary for simple Maps.