Re: Bugs in 1.0.5rc1

Armin Waibel <[email protected]> Tue, 11 Mar 2008 02:22:17 +0100
Newsgroups gmane.comp.jakarta.ojb.user
Message-ID <[email protected]>
Hi Sascha,

Sascha Broich wrote:
> Hi Armin
> 
>> yep, this is the intended behavior. This method (beside user specific
>> ManageableCollection implementations) only allow base collection
>> classes
>> (List, Set,...).
>> The mentioned line is similar to:
>> Set.class.equals(fieldClass)
> 
> Okay, if this is intended. 
> It was just a stumbling block.
> I will look if I can change our code with backward compatibility.

Below you can find a new (backward compatible) version of method 
CollectionTypes#getCollectionClass. Give it a try.


>  
> 
>> You are right, this should not happen. In the OJB test-suite we do
>> several tests using table-per-subclass inheritance and this never
>> happens.
>> Could you post the mapping for class A1, A0 and the source of the
> query
>> then I can try to reproduce your issue.
> 
> The criteria for this issue was build by using the table column name
> 'PHB_USRID'.
> After I changed this to 'addIsNull("m_iUserId") the query succeeded.

Thanks for the detailed description. Now I'm able to reproduce the bug.
I setup a test using table-per-subclass inheritance. This test search 
for a nullified field using a field attribute and then a column attribute:

Criteria c1 = new Criteria()
         .addEqualTo("id_2", id_2)
         .addIsNull("name");
Criteria c2 = new Criteria()
         .addEqualTo("id_2", id_2)
         .addColumnIsNull("NAME");
QueryByCriteria q1 = QueryFactory.newQuery(Executive.class, c1, true);
QueryByCriteria q2 = QueryFactory.newQuery(Executive.class, c2, true);

The first query pass, the second returns the same error you described in 
a previous mail. Will try to fix this ASAP!

regards,
Armin




new version of method CollectionTypes#getCollectionClass
-------------------------------------------------------

// configurable property
private boolean optimized = true;

public Class getCollectionClass(CollectionDescriptor cds) throws 
PersistenceBrokerException
{
     Class result = cds.getCollectionClass();
     if(result == null)
     {
         boolean failed = false;
         Class fieldType = cds.getPersistentField().getType();

         /*
         first check for user specific ManageableCollection type,
         then check for base collection types (List, Set, Vector, 
Collection)
         and check if the collection field type is assignable from the 
predefined
         collection type implementation (predefined/configured 
implemenations of ManageableCollection).
          */
         if (ManageableCollection.class.isAssignableFrom(fieldType))
         {
             result = fieldType;
         }
         else if(Vector.class.isAssignableFrom(fieldType))
         {
             result = cds.isMtoNRelation() ? getManyToManyVector() : 
getOneToManyVector();
             if(!fieldType.isAssignableFrom(result))
             {
                 failed = true;
             }
         }
         else if(List.class.isAssignableFrom(fieldType))
         {
             result = cds.isMtoNRelation() ? getManyToManyList() : 
getOneToManyList();
             if(!fieldType.isAssignableFrom(result))
             {
                 failed = true;
             }
         }
         else if(Set.class.isAssignableFrom(fieldType))
         {
             result = cds.isMtoNRelation() ? getManyToManySet() : 
getOneToManySet();
             if(!fieldType.isAssignableFrom(result))
             {
                 failed = true;
             }
         }
         else if(Collection.class.isAssignableFrom(fieldType))
         {
             result = cds.isMtoNRelation() ? getManyToManyCollection() : 
getOneToManyCollection();
             if(!fieldType.isAssignableFrom(result))
             {
                 failed = true;
             }
         }
         else if(fieldType.isArray())
         {
             result = cds.isMtoNRelation() ? getManyToManyArray() : 
getOneToManyArray();
         }
         else
         {
             failed = true;
         }
         if(failed)
         {
             throw new MetadataException(
                     "Cannot determine a collection type for 
collection/list/set/array field '"
                     + cds.getAttributeName() + "' of type '" + 
fieldType + "' in persistence capable class '"
                     + cds.getClassDescriptor().getClassNameOfObject() + 
"'");
         }
         // performance optimization
         if(optimized)
         {
             cds.setCollectionClass(result);
         }
     }
     return result;
}