unfortunately there is no nice solution to this, short of changing the way castor iterates through resultsets. For our application we couldn't pay the price of counting all the objects in the resultset by iterating through them. I think the fastest way would be to write more code for castor that does a count(*) based on the object type, and the where clause, but doesn't include all the joined tables. This would mean 2 queries would be necessary to get results and size, but at least it would be correct. m
-----Original Message-----
From: Bruce Snyder [mailto:[EMAIL PROTECTED]
Sent: Sun 2/23/2003 5:03 PM
To: [EMAIL PROTECTED]
Cc:
Subject: Re: [castor-dev] Question 5: QueryResults.size()
This one time, at band camp, Keld Helbig Hansen said:
KHH>Sometimes I get QueryResults.size=2 on a query, but there's only one
object in QueryResults.
KHH>E.g.
KHH> query = db.getOQLQuery("SELECT a FROM hansen.playground.Actor a
WHERE a.name=$1");
KHH> query.bind("Keanu Reeves");
KHH>This should only return one object, but QueryResults.size() is 2.
KHH>If I fetch the first object, QueryResults.hasMore() however returns false.
KHH>
KHH>There is a many-to-many relation from actor to movie, and Castor generates
an SQL statement like this:
KHH>
KHH>SELECT actor.id,actor.name,actor_movie.id_movie FROM actor LEFT OUTER JOIN
actor_movie ON actor.id=actor_movie.id_actor WHERE (actor.name = ?)
KHH>
KHH>I'd say that size=2 is wrong. What's the explanation?
Keld,
Actually, the size() method on the QueryResults seems to be broken
at times due to the way that Castor JDO queries and loads objects.
Here is a quick description from the author of the size() method,
Matthew Baird:
-------------------------------------------------------------------------------
If you have an object model that has a one to many where the queried class
is the one, then you will get the wrong number of results reported
by .size().
The reason is Castor builds the queries in a way to try and load all the
results at once, then there is code in castor that looks at the
change in the resultset to know when to switch the object it's creating.
A diagram is probably more useful:
foo has many bar's
foo has id, code, name
bar has id, age, date
So a query to get all foo's will end up returning a resultset like this:
FOO.ID FOO.CODE FOO.NAME BAR.ID BAR.AGE BAR.DATE
------ -------- ------------ ------ ------- --------
1 abc somefoo 123 3 1/1/2001
1 abc somefoo 124 8 1/1/2002
1 abc somefoo 532 1 2/4/2001
2 def someotherfoo 828 .05 6/6/1999
2 def someotherfoo 999 3 1/1/2002
So that represents foo (1) having 3 related bar's and foo(2)
having 2 related bar's. Castor looks at the change in bar.id
as it scrolls through the resultset in order to change from
building foo(1) to foo(2). This get's even more hairy when bar
participates in a 1:M as well as foo. In this case, .size()
will return 5 instead of 2 because it just goes to the end get's
the rowcount then pops back to the front.
-------------------------------------------------------------------------------
HTH.
Bruce
--
perl -e 'print unpack("u30","<0G)[EMAIL
PROTECTED]&5R\"F9E<G)E=\$\!F<FEI+F-O;0\`\`");'
-----------------------------------------------------------
If you wish to unsubscribe from this mailing, send mail to
[EMAIL PROTECTED] with a subject of:
unsubscribe castor-dev
<<winmail.dat>>
