Hi Sascha,

Sascha Broich wrote:
Hi Armin,

The method CollectionTypes#getCollectionClass is correctly
implemented.
First this method checks for user specific collection class
implementations (implementations of ManageableCollection), then this
method try to resolve the collection class implementations for 1:n and
m:n collection-fields (of type Collection, List, Set or array types)
of
persistence capable classes.

The "real bug" is a typo in the OJB.properties file:
replace

CollectionTypes.OneToManySet=org.apache.ojb.broker.util.collections.Man
ageableSet
with

CollectionTypes.OneToManySet=org.apache.ojb.broker.util.collections.Man
ageableHashSet

I will fix this ASAP. Thanks again.

I'm sorry, but the change in the OJB.properties file didn't solve the
problem.
I still get the MetadataException "Cannot determine a collection type
for collection/list/set/array field 'devices' of type 'class
java.util.HashSet' in persistence capable class 'Abc'"

As I wrote: HashSet.class.isAssignableFrom(java.util.Set.class) will
ALWAYS fail.

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)


Please remember, the method can only be successful in the direction
superclass.isAssignableFrom(subclass).
The only superclass of java.util.Set is java.util.Collection.
So as long as there is a HashSet instead of a Set used as field the
check fails, despite the OJB.properties file.

In 1.0.4 this assignable check was against RemovalAwareSet, which is a
subclass of HashSet.

yep, you are right. But now the collection types are configurable in OJB.properties file e.g.
CollectionTypes.OneToManySet=org.apache.ojb.broker.util.collections.ManageableHashSet
So we can't check against an implementation class.

Currently RC1 automatic resolve only base collection types like Collection, List, Vector and Set.
Two workarounds:
1.) If you change field 'devices' to type 'Set' it should work (with patched OJB.properties file). 2.) Directly set a collection implementation class in the collection-descriptor (you can use a shortcut-name for shipped implementations - see documentation):

<collection-descriptor
name="allArticlesInGroup"
element-class-ref="org.apache.ojb.broker.Article"
collection-class="set"
...
</collection-descriptor>


I have to admit that the current behavior isn't perfect ;-), so I will improve class CollectionTypes to be backward compatible with 1.0.4: First check the collection field base type (e.g. subclass of class Set) and then make sure that the ManageableCollection implemetation class is a subclass of the field collection type.

<snip>
if (ManageableCollection.class.isAssignableFrom(fieldType))
{
    result = fieldType;
}
else if(Set.class.isAssignableFrom(fieldType))
{
    result = cds.isMtoNRelation() ? getManyToManySet() : getOneToManySet();
    if(!fieldType.isAssignableFrom(result))
    {
        failed = true;
    }
}
...
</snip>




Another bug is in the statement creation when a subclass is
involved.
Note: A0 is the subclass table from A1, PHB_USRID exists only in A1

1.0.4 creates something like

SELECT
        A0.PHB_ID         ,
        A1.PHB_USRID      ,
FROM
        IPT_PHONEBOOKCSV A0
        INNER JOIN IPT_PHONEBOOK A1
        ON
                A0.PHB_ID = A1.PHB_ID
WHERE
        PHB_USRID IS NULL



1.0.5rc1 creates

SELECT
        A0.PHB_ID         ,
        A1.PHB_ID         ,
        A1.PHB_USRID      ,
FROM
        IPT_PHONEBOOKCSV A0
        INNER JOIN IPT_PHONEBOOK A1
        ON
                A0.PHB_ID = A1.PHB_ID
WHERE
        A0.PHB_USRID IS NULL


The WHERE criteria assignment to A0 the statement produces an
exception
for the nonexisting column A0.PHB_USRID.

Note, that in the SELECT of 1.0.5rc1 is also A1.PHB_ID, which is not
in
the statement of 1.0.4.
If PHB_USRID only exists in A1 then A1 is a subclass of (super) class
A0. In this case it's not allowed to build a query with target class
A0
and fields only existing in A1.
Is this the case? If not, please post some more details (java pseudo
code, class mapping).

class A1
{
  PHB_ID;
  PHB_USRID;
  PHB_NAME;
}

class A0 extends A1
{
  PHB_CSV;
}

And the tables are
Table A1
  PHB_ID
  PHB_USRID
  PHB_NAME

Table A0
  PHB_ID
  PHB_CSV

Because of the inheritance there shouldn't be a need for the column
PHB_USRID in the table for the derived class A0.

The correct statement should be

SELECT
  A0.PHB_ID   ,
  A0.PHB_CSV  ,
  A1.PHB_USRID,
  A1.PHB_NAME
FROM
  A0 INNER JOIN A1 ON A0.PHB_ID = A1.PHB_ID
WHERE A1.PHB_USRID IS NULL

I'm not sure if the 1.0.4 resolved this correct but it didn't add the
alias to the where clause so the database assigned the correct column by
itself.

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.

regards,
Armin



Regards,
Sascha Broich


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to