ibatis-user-java mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Torsten Michelmann" <torsten.michelm...@gmx.de>
Subject Re: Re: RE: Problem populating a List using groupBy
Date Tue, 27 Jun 2006 14:56:27 GMT
Hi Chris,

thank you very much for the prompt response and the kind explanation.
I will give this a try very soon.

-------- Original-Nachricht --------
Datum: Tue, 27 Jun 2006 08:45:06 -0600
Von: Chris Lamey <clamey@localmatters.com>
An: user-java@ibatis.apache.org
Betreff: Re: RE: Problem populating a List using groupBy

> Hello,
> 
> I had the exact same questions:)
> 
> Yes, the docs are out of date, the RowHandler interface has changed.
> 
> Here's an example of RowHandler usage:
> 
> public class WidgetRowHandler implement RowHandler {
> 
>     private List<Widgets> widgets = new ArrayList<Widgets>();
> 
>     public void handleRow(Object valueObject) {
>         
>     	Map resultMap = (Map) valueObject;
>         Widget w = new Widget();        
>         w.setID((String)resultMap.get("widget_id"));
>         w.setName((String)resultMap.get("widget_name"));
>         w.setParentID((String)resultMap.get("widget_parent_id"));
>         
>         widgets.add(w);
>     }
> 
>     public List<Widget> getWidgets() {
>         return this.widgets;
>     }
> }
> 
> Then in your DAO:
> 
> 
>             Map<String, String> params = new HashMap<String, String>();
>             params.put("category_id", categoryID);
>             params.put("invoce_id", invoiceID);
>             WidgetRowHandler wrh = new WidgetRowHandler();
>             sqlMapClient.queryWithRowHandler(
>                     "WIDGET.select_widgets",
>                     params, wrh);
>             return wrh.getWidgets();
> 
> It's a simple example, but the basic idea is that you can pull things
> >from the result set via handleObject, keep them around in your
> RowHandler instance, and other objects can find them there.
> 
> Of course, if you're dealing with large data sets, putting everything
> into a List wouldn't scale all that well.  However, for large data sets
> the RowHandler is very useful because you can process one row in your
> result set at a time, which can be very efficient.
> 
> Cheers,
> Chris
> 
> On Tue, 2006-06-27 at 16:11 +0200, Torsten Michelmann wrote:
> > Hi Chris,
> > 
> > thank you for the pointer to the RowHandler interface.
> > I had a look at the API and I have to admit that I don't completely get
> it how I would have to implement a RowHandler that would create the List.
> > Because my understanding is that the RowHandler is state- and context
> less. This means that I would have to use some global static object to store
> my results from the processed lines which I regard as highly undesirable.
> > But most probably I am missing something, could you please shed some
> more light on this topic?
> > 
> > Thanks a lot in advance.
> > 
> > 
> > (P.S. I checked the Developer Guide and it seems that the RowHandler
> example at p.59 is not completely up to date with regard to the current API as
> it contains (Object,List) in the method signature of handleRow which does
> not exist anymore (or is deprecated, not sure) in the current API.)
> > 
> > 
> > -------- Original-Nachricht --------
> > Datum: Fri, 23 Jun 2006 14:28:29 -0600
> > Von: Chris Lamey <clamey@localmatters.com>
> > An: user-java@ibatis.apache.org, user-java@ibatis.apache.org
> > Betreff: RE: Problem populating a List using groupBy
> > 
> > > Heya,
> > > 
> > > This doesn't address your question directly, but is some background
> for
> > > you.  I am also using iBATIS for the first time in a small but
> somewhat
> > > complex schema.  Along the way I tried using the groupBy support in
> the SqlMap
> > > xml but gave up and went to the RowHandler callback.  The RowHandler
> is so
> > > much easier to work with because of the complete control over what
> result
> > > columns go into which object and what Collection gets which objects. 
> I've
> > > got SQL that joins across multiple tables, recursive joins, outer
> joins, and
> > > other wacky stuff and the groupBy support was a little too imprecise
> for
> > > me.  There's also a bug in 2.1.7 with nested columns in a resultMap,
> which I
> > > think I hit...
> > > 
> > > Anyway, when I wrote to this list about my saga, I was directed at
> > > RowHandler and it made my year.
> > > 
> > > Cheers,
> > > Chris
> > > 
> > > 
> > > -----Original Message-----
> > > From: Torsten Michelmann [mailto:torsten.michelmann@gmx.de]
> > > Sent: Fri 6/23/2006 8:54 AM
> > > To: user-java@ibatis.apache.org
> > > Subject: Problem populating a List using groupBy
> > >  
> > > Hi folks,
> > > 
> > > again me (seems that I am touching all the rather complicated topics
> of
> > > iBatis during my very first project).
> > > The problem is appearing while I try to avoid an N+1 select for a 1:M
> > > relationship (as described on p. 36 in the latest developer guide).
> > > I think that I may be using the groupBy attribute in an incorrect way
> but
> > > I am not sure how it has to be done correctly. (I tried using
> groupBy="ID"
> > > as well as groupBy="id" but that returned the same error).
> > > 
> > > com.ibatis.common.jdbc.exception.NestedSQLException:   
> > > --- The error occurred in global/persistence/mom/MOM_SqlMap.xml.  
> > > --- The error occurred while applying a result map.  
> > > --- Check the MOM.r_getCustomerOrder.  
> > > --- The error happened while setting a property on the result object. 
> > > --- Cause: com.ibatis.common.beans.ProbeException: Could not set
> property
> > > 'customerOrderItemsList' for
> global.persistence.mom.CustomerOrderMapper. 
> > > Cause: java.lang.NullPointerException
> > > Caused by: java.lang.NullPointerException
> > > Caused by: com.ibatis.common.beans.ProbeException: Could not set
> property
> > > 'customerOrderItemsList' for
> global.persistence.mom.CustomerOrderMapper. 
> > > Cause: java.lang.NullPointerException
> > > Caused by: java.lang.NullPointerException
> > > 	at
> > >
> com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:188)
> > > 	at
> > >
> com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForObject(GeneralStatement.java:104)
> > > 	at
> > >
> com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:561)
> > > 	at
> > >
> com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:536)
> > > 	at
> > >
> com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSessionImpl.java:93)
> > > 	at
> > >
> com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForObject(SqlMapClientImpl.java:70)
> > > 
> > > 
> > > //The mapping
> > > 	<resultMap id="r_getCustomerOrder" class="CustomerOrderMapper"
> > > groupBy="orderItemKey.articleKey.articleId">
> > > 		<result property="objectId" column="ID" />
> > > 		<result property="comment" column="COMMENT" />
> > > 		<result property="mom" column="IS_MOM" />
> > > 		<result property="kimStatus" column="KIMSTATUS" />
> > > 		<result property="customerOrderKey.customerId" column="CUSTOMER_ID"
> />
> > > 		<result property="customerOrderKey.orderId" column="ORDERID" />
> > > 		<result property="customerOrderKey.version" column="VERSION" />
> > > 		<result property="customerOrderKey.moduleKey.moduleId"
> > > column="MODULE_ID" />
> > > 		<result property="customerOrderKey.collectionKey.seasonId"
> > > column="SAISON" />
> > > 		<!-- <result
> > > property="customerOrderKey.collectionKey.collectionCategoryId"
> column="SEGMENT" />  not existant within MOM-->
> > > 		<result property="customerOrderKey.collectionKey.segmentId"
> > > column="SEGMENT" />
> > > <!-- 	<result property="customerOrderItemsList" column="{id=ID}"
> > > select="getCustomerOrderItem" />  -->
> > > 		<result property="customerOrderItemsList"
> > > resultMap="MOM.r_getCustomerOrderItem" /> 
> > > 	</resultMap>
> > > 	<resultMap id="r_getOrderItemBase" class="OrderItemBase">
> > > 		<!-- <result property="objectId" column="" />  -->
> > > 		<!-- <result property="salesPrice" column="" />  -->
> > > 		<!-- <result property="recommendedRetailPrice" column="" />  -->
> > > 		<!-- <result property="currency" column="" />  -->
> > > 		<result property="orderItemKey.articleKey.articleId"
> > > column="ARTICLE_NUM" />
> > > 		<result property="orderItemKey.articleColourKey.articleColourId"
> > > column="COLOUR" />
> > > 		
> > > 	</resultMap>
> > > 	<resultMap id="r_getOrderItem" class="OrderItem"
> > > extends="r_getOrderItemBase">
> > > 		<result property="orderedQuantity" column="ORDERED_QUANTITY"/>
> > > 	</resultMap>
> > > 	<resultMap id="r_getCustomerOrderItem" class="CustomerOrderItem"
> > > extends="r_getOrderItem">
> > > 		<result property="size" column="ARTICLE_SIZE" />
> > > 		<result property="length" column="ARTICLE_LENGTH" />
> > > 	</resultMap>
> > > 
> > > //The query 
> > > 			SELECT c.ID, c.COMMENT, c.KIMSTATUS, c.CUSTOMER_ID, c.ORDERID,
> > > c.VERSION, c.MODULE_ID, c.SAISON, c.SEGMENT, c.IS_MOM, a.ARTICLE_NUM,
> d.COLOUR,
> > > d.ORDERED_QUANTITY,e.ARTICLE_SIZE, e.ARTICLE_LENGTH
> > > 			FROM
> > > 				MENU.ARTICLE a inner join MENU.ARTICLE2MENUORDER b on
> > > a.ARTICLE_NUM=b.ARTICLE_NUM
> > > 	            inner join MENU.MENUORDER c on b.MENUORDER_ID=c.ID
> > > 	            left outer join MENU.COLOUR2ARTICLE d on d.ART2MO_ID=b.ID
> > > 	            left outer join MENU.SIZE2ARTICLE e on d.ART2MO_ID=b.ID
> > > 	        WHERE 
> > > 	        	c.ID=#objectId#			
> > > 
> > > 
> > > //Customer Order is providing only methods access an Array, thus the
> > > Wrapper. I have provided this class in order to allow you to ensure
> that I am
> > > not missing anything in here.
> > > public class CustomerOrderMapper extends CustomerOrder {
> > >     public void setCustomerOrderItemsList(List pCustomerOrderItemList)
> {
> > >         if (pCustomerOrderItemList.size() > 0) {
> > >             CustomerOrderItem[] coi= (CustomerOrderItem[])
> > > pCustomerOrderItemList.toArray(new
> CustomerOrderItem[pCustomerOrderItemList.size()]);
> > >             setCustomerOrderItems(coi);
> > >         }
> > >     }
> > > 
> > >     public List getCustomerOrderItemsList() {
> > >         if(getCustomerOrderItems()==null)
> > >         {
> > >             return new ArrayList();
> > >         }
> > >         else
> > >         {
> > >             return Arrays.asList(getCustomerOrderItems());
> > >         }
> > >     }
> > > }
> > > 
> > > 
> > > 
> > > 
> > > -- 
> > > Gruß
> > > Torsten Michelmann
> > > 
> > > "Feel free" - 10 GB Mailbox, 100 FreeSMS/Monat ...
> > > Jetzt GMX TopMail testen: http://www.gmx.net/de/go/topmail
> > > 
> > 

-- 
Gruß
Torsten Michelmann

Echte DSL-Flatrate dauerhaft für 0,- Euro*!
"Feel free" mit GMX DSL! http://www.gmx.net/de/go/dsl

Mime
View raw message