ibatis-user-java mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Jerome Jacobsen" <jerome.jacob...@gentootech.com>
Subject RE: Avoiding N+1 with complex HashMap properties.
Date Fri, 10 Dec 2004 18:22:02 GMT
Darn typo!  Option 2 should say:

HashMap customer = customerDao.getCustomer(id);
HashMap address = customer.get("address");
out.println("customer state = " + address.get("state"));

customer.get("address") instead of customerDao.get("address")

We're getting the 'address' HashMap from the 'customer'
HashMap.

> -----Original Message-----
> From: Jerome Jacobsen [mailto:jerome.jacobsen@gentootech.com]
> Sent: Friday, December 10, 2004 12:49 PM
> To: ibatis-user-java@incubator.apache.org
> Subject: RE: Avoiding N+1 with complex HashMap properties.
>
>
> Just to be clear, here are examples of what I'm talking about.
>
> Option 1:  Single hashmap with indexed property style keys.
>
> HashMap customer = customerDao.getCustomer(id);
> out.println("customer state = " + customer.get("address.state"));
>
> Option 2:  Nested hashmaps.
>
> HashMap customer = customerDao.getCustomer(id);
> HashMap address = customerDao.get("address");
> out.println("customer state = " + address.get("state"));
>
>
> I have no preference as to which way is supported, as long as:
>   - The exception doesn't occur.
>   - I can access the properties using the 'indexed property'
>     style in JSP.
>
> I'm not sure how JSTL/JSP would handle the nested HashMap versus
> handling the single HashMap.
>
> In JSP not sure if I can do this for both implementations
> above:
>
> Customer State = <c:out value="${customer.address.state}"/>
>
> If JSP/JSTL only supports one of these implementation options
> then that would be my preference for ibatis too.
>
> Regards,
>
> Jerome
>
> > -----Original Message-----
> > From: Clinton Begin [mailto:clinton.begin@gmail.com]
> > Sent: Friday, December 10, 2004 10:09 AM
> > To: jerome.jacobsen@gentootech.com
> > Cc: ibatis-user-java@incubator.apache.org
> > Subject: Re: Avoiding N+1 with complex HashMap properties.
> >
> >
> > Tough call.  Some people want it stored as a single property (e.g.
> > imagine the key is a classname), and others want it stored nested.
> >
> > Currently, as you've discovered, it's not nested.
> >
> > I would suggest that if you have a complex object model, then you
> > should model it using JavaBeans.  Maps are very loose, unpredictable
> > and limited.
> >
> > Cheers,
> > Clinton
> >
> >
> > On Fri, 10 Dec 2004 10:03:16 -0500, Jerome Jacobsen
> > <jerome.jacobsen@gentootech.com> wrote:
> > > Hello,
> > >
> > > I'm using SQL Maps 2.08.  I was hoping I could do the following
> > > but I get a ProbeException.  Should this be supported?
> > >
> > > <resultMap id="get-customer-period-result"
> > >            class="java.util.HashMap">
> > >   <result property="customerNum"
> > >           column="CUSTOMER_NUMBER"
> > >           columnIndex="1"/>
> > >   <result property="category.id"
> > >           column="CATEGORY_ID"
> > >           columnIndex="2"/>
> > >   <result property="category.parentId"
> > >           column="PARENT_CATEGORY_ID"
> > >           columnIndex="3"/>
> > >   <result property="category.description"
> > >           column="CATEGORY_DESC"
> > >           columnIndex="4"/>
> > >   ...
> > > </resultMap>
> > >
> > > <statement id="getCustomerPeriodSummary"
> > >            resultMap="get-customer-period-result">
> > >   SELECT CPS.CUSTOMER_NUMBER,
> > >          PC.CATEGORY_ID,
> > >          PC.PARENT_CATEGORY_ID,
> > >          PC.DESCRIPTION AS CATEGORY_DESC,
> > >          PC.SEQUENCE AS CATEGORY_SEQUENCE,
> > >          ...
> > >     FROM CUSTOMER_PERIOD_SUMMARY CPS, PRODUCT_CATEGORY PC,
> > SALES_PERIOD SP
> > >    WHERE CPS.CUSTOMER_NUMBER = #value#
> > >      AND CPS.CATEGORY_ID = PC.CATEGORY_ID
> > >      AND CPS.PERIOD_ID = SP.PERIOD_ID
> > > ORDER BY CATEGORY_SEQUENCE
> > > </statement>
> > >
> > > I was hoping that sqlmaps would store the 'category.id',
> > > 'category.parentId', 'category.description' either in a nested
> > > HashMap (key of 'category') or store the values in the top
> > > level HashMap with those keys ('category.id', etc.)
> > >
> > > However neither case appears to happen and I get the
> > > exception below.  I realize that I can map the complex
> > > properties with separate selects but I want to avoid the
> > > N+1 query problem.  So I do the join instead.
> > >
> > > com.ibatis.common.beans.ProbeException: There is no WRITEABLE
> > property named
> > > 'id' in class 'java.lang.Object'
> > >         at
> > com.ibatis.common.beans.ClassInfo.getSetter(ClassInfo.java:146)
> > >         at
> > >
> > com.ibatis.common.beans.ComplexBeanProbe.setProperty(ComplexBeanPr
> > obe.java:3
> > > 34)
> > >         at
> > >
> > com.ibatis.common.beans.ComplexBeanProbe.setObject(ComplexBeanProb
> > e.java:231
> > > )
> > >         at
> > com.ibatis.common.beans.GenericProbe.setObject(GenericProbe.java:69)
> > >         at
> > >
> > com.ibatis.sqlmap.engine.exchange.ComplexDataExchange.setData(Comp
> > lexDataExc
> > > hange.java:87)
> > >         at
> > >
> > com.ibatis.sqlmap.engine.mapping.result.BasicResultMap.setResultOb
> > jectValues
> > > (BasicResultMap.java:231)
> > >         at
> > >
> > com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback.hand
> > leResultOb
> > > ject(RowHandlerCallback.java:63)
> > >         at
> > >
> > com.ibatis.sqlmap.engine.execution.SqlExecutor.handleResults(SqlEx
> > ecutor.jav
> > > a:350)
> > >         at
> > >
> > com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQuery(SqlExe
> > cutor.java
> > > :179)
> > >         at
> > >
> > com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.sqlExe
> > cuteQuery(
> > > GeneralStatement.java:200)
> > >         at
> > >
> > com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.execut
> > eQueryWith
> > > Callback(GeneralStatement.java:168)
> > >         at
> > >
> > com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.execut
> > eQueryForL
> > > ist(GeneralStatement.java:118)
> > >         at
> > >
> > com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(
> > SqlMapExec
> > > utorDelegate.java:626)
> > >         at
> > >
> > com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(
> > SqlMapExec
> > > utorDelegate.java:598)
> > >         at
> > >
> > com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForList(SqlMa
> > pSessionIm
> > > pl.java:107)
> > >         at
> > >
> > org.springframework.orm.ibatis.SqlMapClientTemplate$3.doInSqlMapCl
> > ient(SqlMa
> > > pClientTemplate.java:202)
> > >         at
> > >
> > org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMap
> > ClientTemp
> > > late.java:142)
> > >         at
> > >
> > org.springframework.orm.ibatis.SqlMapClientTemplate.executeWithLis
> > tResult(Sq
> > > lMapClientTemplate.java:164)
> > >         at
> > >
> > org.springframework.orm.ibatis.SqlMapClientTemplate.queryForList(S
> > qlMapClien
> > > tTemplate.java:200)
> > >         at
> > >
> > com.giv.dashboard.dao.db.ibatis.SqlMapSalesStatisticsDAO.getCatego
> > ryStatsFor
> > > Customer(SqlMapSalesStatisticsDAO.java:28)
> > >         at
> > >
> > com.giv.dashboard.DashboardImpl.getCategorySummaries(DashboardImpl
> > .java:42)
> > >         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> > >         at
> > >
> > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorIm
> > pl.java:39
> > > )
> > >         at
> > >
> > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAc
> > cessorImpl
> > > .java:25)
> > >         at java.lang.reflect.Method.invoke(Method.java:324)
> > >         at
> > >
> > org.springframework.aop.support.AopUtils.invokeJoinpointUsingRefle
> > ction(AopU
> > > tils.java:295)
> > >         at
> > >
> > org.springframework.aop.framework.ReflectiveMethodInvocation.invok
> > eJoinpoint
> > > (ReflectiveMethodInvocation.java:154)
> > >         at
> > >
> > org.springframework.aop.framework.ReflectiveMethodInvocation.proce
> > ed(Reflect
> > > iveMethodInvocation.java:121)
> > >         at
> > >
> > org.springframework.transaction.interceptor.TransactionInterceptor
> > .invoke(Tr
> > > ansactionInterceptor.java:56)
> > >         at
> > >
> > org.springframework.aop.framework.ReflectiveMethodInvocation.proce
> > ed(Reflect
> > > iveMethodInvocation.java:143)
> > >         at
> > >
> > org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDyn
> > amicAopPro
> > > xy.java:174)
> > >         at $Proxy0.getCategorySummaries(Unknown Source)
> > >         at
> > >
> > com.giv.dashboard.web.spring.ViewCategoriesController.handleReques
> > tInternal(
> > > ViewCategoriesController.java:62)
> > >         at
> > >
> > org.springframework.web.servlet.mvc.AbstractController.handleReque
> > st(Abstrac
> > > tController.java:128)
> > >         at
> > >
> > org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter
> > .handle(Si
> > > mpleControllerHandlerAdapter.java:44)
> > >         at
> > >
> > org.springframework.web.servlet.DispatcherServlet.doService(Dispat
> > cherServle
> > > t.java:532)
> > >         at
> > >
> > org.springframework.web.servlet.FrameworkServlet.serviceWrapper(Fr
> > ameworkSer
> > > vlet.java:366)
> > >         at
> > >
> > org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkSe
> > rvlet.java
> > > :317)
> > >         at
> javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
> > >         at
> javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
> > >         at
> > >
> > com.evermind.server.http.ResourceFilterChain.doFilter(ResourceFilt
> > erChain.ja
> > > va:65)
> > >         at
> oracle.security.jazn.oc4j.JAZNFilter.doFilter(Unknown Source)
> > >         at
> > >
> > com.evermind.server.http.ServletRequestDispatcher.invoke(ServletRe
> > questDispa
> > > tcher.java:604)
> > >         at
> > >
> > com.evermind.server.http.ServletRequestDispatcher.forwardInternal(
> > ServletReq
> > > uestDispatcher.java:317)
> > >         at
> > >
> > com.evermind.server.http.HttpRequestHandler.processRequest(HttpReq
> > uestHandle
> > > r.java:790)
> > >         at
> > >
> > com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler
> > .java:270)
> > >         at
> > >
> > com.evermind.server.http.HttpRequestHandler.run(HttpRequestHandler
> > .java:112)
> > >         at
> > >
> > com.evermind.util.ReleasableResourcePooledExecutor$MyWorker.run(Re
> > leasableRe
> > > sourcePooledExecutor.java:192)
> > >         at java.lang.Thread.run(Thread.java:534)
> > >
> > >
> >


Mime
View raw message