Re: selectRelationshipObjects and addPrefetch results in classcastexception

From: Twan Kogels (twa..wansoft.com)
Date: Wed Nov 24 2004 - 10:29:08 EST

  • Next message: Alex Gunawan Wibowo: "Cayenne + Struts form.."

    Hello Andrus,

    Thanks for the reply, i've looked at CAY-15 and that seems to be a great
    feature for a future version of cayenne. In the meantime i just use my
    favorite sqltemplate solution ;-)

    Cheers,
    Twan

    At 15:31 24-11-2004, you wrote:
    >Ok, now I see what's going on... This is indeed related to an existing
    >limitation in Cayenne - prefetches are not supported for flattened
    >relationships (CAY-15).
    >
    >So "partitionBySource" naively assumes that if "incoming" relationship is
    >to-many, then reverse is to-one. Regardless of when CAY-15 is implemented,
    >I guess I need to clean this code to avoid such assumption...
    >
    >Andrus
    >
    >
    >
    > > Hello Andrus,
    > >
    > > I've ran a debugger and found the following:
    > > ====================
    > > (SelectObserver.java)
    > > static Map partitionBySource(ObjRelationship incoming, List
    > > prefetchedObjects) {
    > > ....
    > > Map toManyLists = MapUtils.lazyMap(new HashMap(), listFactory);
    > > Iterator destIterator = prefetchedObjects.iterator();
    > > while (destIterator.hasNext()) {
    > > DataObject destinationObject = (DataObject)
    > > destIterator.next(); DataObject sourceObject = null;
    > > if (reverseRelationship != null) {
    > > sourceObject =
    > > (DataObject) destinationObject.readProperty(
    > > reverseRelationship.getName());
    > > }
    > > ....
    > > }
    > > ====================
    > >
    > > When the debugger enters the iterator for the first time the following
    > > is true: ====================
    > > "destinationObject" is of type "freesite.project.Project".
    > > reverseRelationship (objNam: java.lang.String = "galleries",
    > > targetEntityName: java.lang.String = "Gallery")
    > > ====================
    > >
    > > When the following code get executed:
    > > ====================
    > > (DataObject) destinationObject.readProperty(
    > > reverseRelationship.getName());
    > > ====================
    > >
    > > The following function is called:
    > > ====================
    > > (CayenneDataObject.java)
    > > public Object readProperty(String propName) {
    > > resolveFault();
    > >
    > > Object object = readPropertyDirectly(propName);
    > >
    > > // must resolve faults immediately
    > > if (object instanceof Fault) {
    > > object = ((Fault) object).resolveFault(this, propName);
    > > writePropertyDirectly(propName, object);
    > > }
    > >
    > > return object;
    > > }
    > > =====================
    > >
    > > The "propName" parameter has value "galleries".
    > > The returned "object" is of type
    > > "org.objectstyle.cayenne.access.ToManyList" (relationship:
    > > java.lang.String = "galleries", source:
    > > org.objectstyle.cayenne.DataObject =
    > > "{freesite.project.Project}")
    > >
    > > I suspect that the ClassCastException is thrown when the code tries to
    > > cast a "ToManyList" to a "DataObject". Which isn't possible ;-)
    > >
    > > Twan
    > >
    > > At 23:04 23-11-2004, you wrote:
    > >
    > >> > Is there a known problem when using
    > >> > "QueryUtils.selectRelationshipObjects" in combination with
    > >> > "addPrefetch"?
    > >>
    > >>Not known to me ;-) QueryUtils methods are mostly used for internal
    > >> Cayenne tasks, so they are not tested with all possible usage
    > >> scenarios.
    > >>
    > >>Can you run this in debugger to tell what class is actually returned?
    > >> Default Java behavior of throwing ClassCastException without specifying
    > >> what class caused it is not that helpful.
    > >>
    > >>Thanks
    > >>Andrus
    > >>
    > >>
    > >> >
    > >> > Because i have a function which uses those 2 functions:
    > >> > =============
    > >> > public List findAllWithExp(GalleryCategory cat) {
    > >> > SelectQuery query =
    > >> QueryUtils.selectRelationshipObjects(_context,
    > >> > cat,
    > >> > "galleries");
    > >> > query.addPrefetch("projecten");
    > >> >
    > >> > return _context.performQuery(query);
    > >> > }
    > >> > =============
    > >> >
    > >> > GalleryCategory (variable cat) has zero or more Gallery objects
    > >> (many-to-many relationship). Those Gallery objects can be reached by
    > >> the
    > >> > "galleries" relationship of GalleryCategory:
    > >> > =============
    > >> > SelectQuery query = QueryUtils.selectRelationshipObjects(_context,
    > >> cat, "galleries");
    > >> > =============
    > >> > The above code return all Gallery objects of "cat" (a
    > >> GalleryCategory). This works perfect.
    > >> >
    > >> > But when i add a prefetch to my selectquery i receive a
    > >> > classcastexception: =============
    > >> > java.lang.ClassCastException
    > >> > at
    > >> >
    > >>
    > org.objectstyle.cayenne.access.util.SelectObserver.partitionBySource(SelectObserver.java:253)
    > >> > at
    > >> >



    This archive was generated by hypermail 2.0.0 : Wed Nov 24 2004 - 10:24:56 EST