Re: SQLTemplate with addPrefetch?

From: Twan Kogels (twa..wansoft.com)
Date: Wed Aug 25 2004 - 04:07:03 EDT

  • Next message: Claudio Rosati: "R: R: Unable to build the right expression"

    Hello Tore,

    >>where.add(" (opleiding.the_geom && GeometryFromText('BOX3D(" +
    >
    >Nice to see someone else playing with postgis and cayenne :)

    What a coincidence, i thought i was one of the very few using postgis ;-)
    Your also using mapserver?

    >>Is it possible to prefetch relationships when using SQLTemplate?
    >
    >Take a look at PrefetchHelper
    >http://www.objectstyle.org/cayenne/api/cayenne/org/objectstyle/cayenne/
    >access/util/PrefetchHelper.html
    >
    >Try something like:
    >String query=".." //query with a lot of joins and non standard where
    >statements
    >SQLTemplate rawSelect = new SQLTemplate(Opleiding.class, query, true);
    >List opleidingen = ctxt.performQuery(rawSelect);
    >PrefetchHelper.resolveToOneRelations(ctxt, opleidingen,
    >"waardeopleiding");
    >
    >If I remember correctly this will result in a huge query looking like
    >"select .... from table where field in (....)". This trick take some
    >time if your opleidingen List is very long..

    Thanks for the suggestion, i tryed but i'm stuck with a ClassCastException.
    I'm now using the following code:
    ===========
           DataContext ctxt =
    BasicServletConfiguration.getDefaultContext(request.getSession());
           SQLTemplate rawSelect = new SQLTemplate(Locatie.class,
    query.toString(), true);
           List locaties = ctxt.performQuery(rawSelect);
           PrefetchHelper.resolveToOneRelations(ctxt, locaties, "organisatie");

           iter=locaties.iterator();
           while(iter.hasNext()){
             Locatie l=(Locatie)iter.next();
             System.out.println(l.getNaam()+" - "+l.getLocatieId()+" -
    "+l.getOrganisatie().getNaam());
           }
    ===========

    The "resolveToOneRelations()" functions throws the ClassCastException. I've
    traced it down to another line in cayenne itself:

    ===========
    (in PrefetchHelper resolveToOneRelations() )
             List oids = new ArrayList(nobjects);

             for (int i = 0; i < nobjects; i++) {
                 DataObject sourceObject = (DataObject) objects.get(i);
                 DataObject targetObject =
                     (DataObject) sourceObject.readPropertyDirectly(relName);

                 ObjectId oid = targetObject.getObjectId();
                 oids.add(oid);
             }
    ===========

    The "(DataObject) sourceObject.readPropertyDirectly(relName);" throws the
    ClassCastException.

    Strange thing is when i try:
    ===========
           DataContext ctxt =
    BasicServletConfiguration.getDefaultContext(request.getSession());
           SQLTemplate rawSelect = new SQLTemplate(Locatie.class,
    query.toString(), true);
           List locaties = ctxt.performQuery(rawSelect);
           //PrefetchHelper.resolveToOneRelations(ctxt,
    locaties, "organisatie"); //<- commented out

           iter=locaties.iterator();
           while(iter.hasNext()){
             Locatie l=(Locatie)iter.next();
             System.out.println(l.getNaam()+" - "+l.getLocatieId()+" -
    "+l.getOrganisatie().getNaam());
           }
    ===========
    everything goes oke. When i call "l.getOrganisatie().getNaam()" the
    relationship object is extracted from the database automatic (i see a query).

    My relationship looks like:
    ===========
    Locatie has a one to one relationship with Organisatie. The relationship is
    called "organisatie" and points to target "Organisatie".

    <db-entity name="Locatie">
                     <db-attribute name="locatieid" type="INTEGER"
    isPrimaryKey="true" isMandatory="true"/>
                     <db-attribute name="naam" type="VARCHAR"
    isMandatory="true" length="255"/>
                     <db-attribute name="organisatieid" type="INTEGER"/>
             </db-entity>

    <db-entity name="Organisatie">
                     <db-attribute name="naam" type="VARCHAR"
    isMandatory="true" length="255"/>
                     <db-attribute name="organisatieid" type="INTEGER"
    isPrimaryKey="true" isMandatory="true"/>
             </db-entity>

    <obj-relationship name="organisatie" source="Locatie" target="Organisatie"
    db-relationship-path="organisatie"/>

    <obj-relationship name="locaties" source="Organisatie" target="Locatie"
    db-relationship-path="locaties"/>
    ===========

    I suspect that i have the wrong value in the third parameter of
    resolveToOneRelations, but i can't seem to find one that's working (i've
    tryed Organisatie, organisatie.naam, organisatie, organisatieid).

    Here's the orginal exception trace:
    ===========
    java.lang.ClassCastException
             at
    org.objectstyle.cayenne.access.util.PrefetchHelper.resolveToOneRelations(PrefetchHelper.java:98)
             at x.zoeken.ZoekAction.myExecute(ZoekAction.java:66)
             at x.BasisAction.execute(BasisAction.java:33)
             at
    org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:484)
             at
    org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:274)
             at
    org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482)
             at
    org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525)
             at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
             at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
             at
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
             at
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
    ===========

    Twan



    This archive was generated by hypermail 2.0.0 : Wed Aug 25 2004 - 04:04:37 EDT