Hello list,
We noticed that Castor 1.2 is returning duplicate objects when the "IN" clause
is used in the select query. The duplicates will be however eliminated with an
"ORDER BY" clause on the primary key. Is this behavior "by design"? Because we
had quite a hard time until we found the problem and its workaround... or do
you have better suggestions than imposing this ordering?
The explanation can be seen in the below Castor code snippets. The Object is
created based on the identity variable. The identity is taken by moving forward
in the Resultset until the first different value is found. For that Identity
Castor is creating the Object. BUT if the Result set is not ordered on the
primary key then the same value can come more than once to the identity so
Castor will create the object more than one time for the same value. In other
words, it duplicates the result.
Thanks,
J
code from OQLQueryImpl.java:
public boolean hasMore(final boolean skipError) throws PersistenceException
{
Object identity;
if (_lastObject != null) {
return true;
}
if (_results == null) {
return false;
}
try {
identity = _results.nextIdentity();
while (identity != null) {
try {
_lastObject = _results.fetch();
if (_lastObject != null) {
break;
}
} catch (ObjectNotFoundException except) {
// Object not found, deleted, etc. Just skip to next one.
identity = _results.nextIdentity();
} catch (PersistenceException except) {
// Error occured. If not throwing exception just skip to
// next object.
identity = _results.nextIdentity();
if (!skipError) {
throw except;
}
}
}
if (identity == null) {
_results.close();
_results = null;
}
} catch (PersistenceException except) {
_results.close();
_results = null;
if (!skipError) {
throw except;
}
}
return (_lastObject != null);
}
and respectively in SQLQuery.java:
// We move forward in the ResultSet, until we see another identity
or run out of rows.
while (_rs.next()) {
// Load identity from current row.
currentIdentity = loadSQLIdentity();
// Compare with wantedIdentity and determine if it is a new one.
if (identitiesEqual(wantedIdentity, currentIdentity)) {
// Load next row of object data from _rs into <_fields>
array.
loadRow(_fields, originalFieldNumber, false);
} else {
// We are done with all the rows for our obj. and still
have rows left.
_lastIdentity = currentIdentity;
// As stamp is never set, this function always returns null
... ???
// (Don't ask me, it was like that before I modified the
code! :-)
return stamp;
}
}
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email