Re: selectRelationshipObjects and addPrefetch results in classcastexception

From: Andrus Adamchik (andru..bjectstyle.org)
Date: Wed Nov 24 2004 - 09:31:09 EST

  • Next message: Andrus Adamchik: "Re: remote access to cayenne as in eodistribution"

    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 - 09:31:11 EST