views:

423

answers:

2

I have a two ibatis sql maps that are linked together via a sub select like the simplified example below:

<resultMap id="order" class="Order">
  <collection property="orderLines" ofType="OrderLine" resultMap=”orderLine”/>
</resultMap>

I have an order object that contains a collection of line objects that are returned by a join and an association. I wish to perform some row handler functionality on every line that is returned by the nested association that returns the order lines.

I know that this can be achieved by passing in a IListRowHandler to the queryWithRowHandler call when calling the spring sqlmapclienttemplate for a query for just a list of OrderLine objects, but this does not allow me to use a rowhandler on the subselect collection when making a call only on the parent sql map, order in this example.

Is there any way to declaritively assign a rowhandler class to a specific resultmap or select statement within an ibatis sql map? As this is the kind of functionality i feel should be there. Or alternatively i am open to suggestions on modifying each instance of the row objects returned by the sub select as they are returned rather than interrogating the fully built order object and manipulating them after the fact.

+1  A: 

It sounds like you are using N+1 select approach, which could result in numerous selects executed even for a simple query and that is usually not desirable. See "Nested Results for Association" section in iBatis User Guide that provides an alternative solution to the issue, basically you can do a join in your main query and then use aggregation at the resultMap level to map to your object model, so in result you can simply use a row handler on the main query.

Eugene Kuleshov
+1 for nested results for association, i have used this in other queries that i have and this can be changed to suit. I could then use a rowhandler on the main query but it returns one composite order object so i would still have to programatically navigate the order lines in turn and modify them. I wondered if there was a way to do this as they were joined in the query via a specification of a handler on a resultmap - therefore activated as each instance of that object was built.
TomY
+1  A: 

I have had a look through the iBatis documentation for something that will suit without success.

So i have implemented the following solution:

On the Order.setOrderLines(collection orderLines) method that is populated via ibatis as a result of the query execution, I have implemented a handler method that manipulates each of the orderLines within the collection that is about to be set on the Order.

This doesn't do achieve the interception of each nested object as it is instantiated and before it is added to the collection, but it does the job, and performs it early enough and in a query agnostic way so that it is activated any time a query utilises the Order resultMap as a return value.

I'm happy to mark any declarative type solution that perform the task as I first wanted as the answer, if someone comes forward with one!

TomY