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 17:48:54 GMT
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