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