db-ojb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Armin Waibel <arm...@apache.org>
Subject Re: Referencing an abstract class. The next turn...
Date Tue, 12 Oct 2004 10:53:24 GMT
Hi Carsten and Tom,

I assume (haven't a test case yet) there could be a problem when using 
multiple joined table.

Say we have a base class Animal and class Dog extend Animal. Class Zoo 
has a 1:n reference to Animal, defined like

<collection-descriptor
   name="allAnimals"
   auto-retrieve="true"
   auto-update="true"
   element-class-ref="Animal"

   <inverse-foreignkey field-ref="id"/>

</collection-descriptor>

and we store two Animal objects (A1, A2) and one Dog object (D3) - 
shouldn't be a problem. See test case 
org....broker.InheritanceMultipleTableTest

Now the user would expect that this collection contains all animals with 
it's associated type (A1, A2, D3 - 1,2,3 are PK's). If you only use the 
"extent" feature or "ojbConcreteClass" (map different classes to the 
same table) the result will be of that kind.
But when using "multiple joined table" the result will be (A1, A2, A3), 
in which A3 is the Animal class instance of Dog D3. In table ANIMAL 
there is no further information specify that ID 3 represents an instance 
of Dog, so OJB create an instance of Animal for ID 3.
So this behavior is different from the other Inheritance-mapping strategies.
(If the collection descriptor element-class-ref="Dog" only instances of 
Dog will be returned).

Carsten does this describe your problem?

regards,
Armin


Thomas Dudziak wrote:
> Carsten Spräner_Ext wrote:
> 
>> Hello Tom,
>>
>> here is my repository_test.xml:
>>
>> <class-descriptor class="db.A" table="A" isolation-level
>> ="read-uncommitted">
>>  <extent-class class-ref="db.B"/>
>>  <field-descriptor name="id" id="1" column="ID" primarykey="true"
>> autoincrement="true" jdbc-type="BIGINT" />
>>  <field-descriptor name="aAttr" id="1" column="A_ATTR" 
>> jdbc-type="VARCHAR"
>> />
>>  <field-descriptor name="colId" jdbc-type="BIGINT" access="anonymous"
>> column="COL_ID" />
>> </class-descriptor>
>>
>> <class-descriptor class="db.B" table="B" isolation-level
>> ="read-uncommitted">
>>  <field-descriptor name="id" id="1" column="ID" primarykey="true"
>> autoincrement="true" jdbc-type="BIGINT" />
>>  <field-descriptor name="superID" id="1" column="SUPER_ID" jdbc-type
>> ="BIGINT" access="anonymous"/>
>>  <field-descriptor name="bAttr" id="2" column="B_ATTR" 
>> jdbc-type="VARCHAR"
>> />
>>  <reference-descriptor name="super"
>>    auto-update="true"
>>    auto-retrieve="true"
>>    class-ref="db.A">
>>     <foreignkey field-ref="superID"/>
>>  </reference-descriptor>
>> </class-descriptor>
>>
>> <class-descriptor class="db.Col" table="COL" isolation-level
>> ="read-uncommitted">
>>  <field-descriptor name="id" id="1" column="ID" primarykey="true"
>> autoincrement="true" jdbc-type="BIGINT" />
>>  <collection-descriptor
>>    name="aCol"
>>    auto-retrieve="true"
>>    auto-update="true"
>>    element-class-ref="db.A"
>>  >
>>    <inverse-foreignkey field-ref="colId"/>
>>  </collection-descriptor>
>> </class-descriptor>
>>  
>>
> Hmm, since you have an explicit <extent-class> in the descriptor db.A, 
> you don't need either superID or the super-reference. In fact, I think 
> they give you problems instead. (Btw, you don't need the 'id' XML 
> attribute for your fields either, I think.)
> Also, you shouldn't use anonymous fields for collection foreign keys 
> (field colId) because that is not well supported. Also this field has to 
> be in db.B, too.
> So try this:
> 
> <class-descriptor class="db.A"
>                  table="A"
>                  isolation-level="read-uncommitted">
>  <extent-class class-ref="db.B"/>
>  <field-descriptor name="id"
>                    column="ID"
>                    primarykey="true"
>                    autoincrement="true"
>                    jdbc-type="BIGINT" />
>  <field-descriptor name="aAttr"
>                    column="A_ATTR"
>                    jdbc-type="VARCHAR"/>
>  <field-descriptor name="colId"
>                    jdbc-type="BIGINT"
>                    column="COL_ID" />
> </class-descriptor>
> 
> <class-descriptor class="db.B"
>                  table="B"
>                  isolation-level="read-uncommitted">
>  <field-descriptor name="id"
>                    column="ID"
>                    primarykey="true"
>                    autoincrement="true"
>                    jdbc-type="BIGINT" />
>  <field-descriptor name="bAttr"
>                    column="B_ATTR"
>                    jdbc-type="VARCHAR"/>
>  <field-descriptor name="colId"
>                    jdbc-type="BIGINT"
>                    column="COL_ID" />
> </class-descriptor>
> 
> <class-descriptor class="db.Col"
>                  table="COL"
>                  isolation-level="read-uncommitted">
>  <field-descriptor name="id"
>                    column="ID"
>                    primarykey="true"
>                    autoincrement="true"
>                    jdbc-type="BIGINT" />
>  <collection-descriptor
>    name="aCol"
>    auto-retrieve="true"
>    auto-update="true"
>    element-class-ref="db.A"
>  >
>    <inverse-foreignkey field-ref="colId"/>
>  </collection-descriptor>
> </class-descriptor>
> 
> See here for details on mapping via <extent-class> or via multiple 
> joined tables:
> 
> http://db.apache.org/ojb/docu/guides/advanced-technique.html#Mapping+Inheritance+Hierarchies

> 
> 
>> I got the first error fixed in the ClassDesriptor. In the method
>> getFieldDescriptorByName it only returns the FieldDescriptors of its own.
>> It does not look in the baseClass if it has one. The following code fixes
>> this problem:
>>
>>    /**
>>     * Returns the matching {@link FieldDescriptor}.
>>     */
>>    public FieldDescriptor getFieldDescriptorByName(String name)
>>    {
>>        if (name == null || m_FieldDescriptions == null)
>>        {
>>            return null;
>>        }
>>
>>        if (m_fieldDescriptorNameMap == null)
>>        {
>>            HashMap nameMap = new HashMap();
>>
>>            FieldDescriptor[] descriptors = getFieldDescriptions();
>>            for (int i = descriptors.length - 1; i >= 0; i--)
>>            {
>>                FieldDescriptor fld = descriptors[i];
>>                nameMap.put(fld.getPersistentField().getName(), fld);
>>            }
>>
>>            m_fieldDescriptorNameMap = nameMap;
>>        }
>>        // OLD: return (FieldDescriptor)
>> m_fieldDescriptorNameMap.get(name);
>>        /****************** FIX ***********************/
>>        FieldDescriptor fd = (FieldDescriptor)
>> m_fieldDescriptorNameMap.get(name);
>>        if( fd == null ) {
>>            String baseClass = getBaseClass();
>>            if( baseClass == null ) return null;
>>            ClassDescriptor cld  = getRepository().getDescriptorFor(
>> baseClass );
>>            fd = cld.getFieldDescriptorByName( name );
>>        }
>>        return fd;
>>    }
>>  
>>
> You certainly shouldn't need to have to modify OJB for your ends. 
> Mapping abstract classes/interfaces is well supported (because everybody 
> uses them :-) ).
> 
> Tom
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
> For additional commands, e-mail: ojb-dev-help@db.apache.org
> 
> 
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org


Mime
View raw message