db-ojb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Lorenz Froihofer <Loren...@gmx.at>
Subject Re: [OJB] Issue #OJB 257 modified
Date Sun, 09 May 2004 20:30:36 GMT
Hi,

I'm sorry to post the reply here but I cannot change the ticket 
information in the scarab system. For the OJB module I only requested 
observer privileges. I can add new tickets but cannot change them. 
Unfortunately, I cannot even try to request other privileges.

> Does the clone method copies the AbstractEntity reference too? 
 > If yes, there should be no problem, because the copied
 > AbstractEntity has a populated PK field (expect you declare the
 > PK field as anonymous too - this is not allowed).

The AbstractEntity is used only to store some common attributes of all 
entities. Normally, I would declare the AbstractEntity as "public 
abstract class" but this is not possible because the OJB repository does 
not support abstract classes to my understanding.

I am not sure if I fully understand your question. There is no reference 
to an AbstractEntity in my application because I never instantiate 
AbstractEntity objects. Only subclasses of the AbstractEntity class are 
used. The reference to AbstractEntity that I describe in the problem 
description of issue 257 is the one that is used by OJB.

The AbstractEntity class declares a field "id" of type Integer that is 
used as the primary key field for all subclasses. I do not declare any 
fields as anonymous in my repository_user.xml.


What I would like to do:
========================
Declare the AbstractEntity as "public abstract class" and use a 
<class-descriptor> with an attribute like abstract="true" in the 
repository_user.xml. In this class-descriptor I declare all fields of 
the abstract entity, including the primary key id field.

In class-descriptors of "real" entities, I only declare the additional 
attributes that are not already contained in the AbstractEntity 
class-descriptor.

Furthermore, I would like to use different tables for AbstractEntity and 
each of the subclasses.

This approach reduces the overhead for the common attributes because I 
can fully encapsulate them in the AbstractEntity class and the 
corresponding table.

What I do:
==========
As abstract classes are not supported, I declare the AbstractEntity 
class as "public class" instead of "public abstract class". This allows 
OJB to instantiate objects of the AbstractEntity class. I never use 
instances of this class in my application.

In the class-descriptor of "real" entities I declare the primary key 
"id" field again. Note that in Java this is the id field declared in the 
AbstractEntity class. Furthermore, I use a
<reference-descriptor name="super" class-ref="...AbstractEntity" ...>
   <foreign-key field-ref="id" />
</reference-descriptor<
in the repository file for all subclasses of AbstractEntity.

I have different tables for AbstractEntity and each of the subclasses. 
Each of these tables contains an id field for the primary key value. The 
value of the id field is unique accross all subclasses of AbstractEntity.

The problem:
============
The AbstractEntity implements Cloneable. If I do not call the clone() 
method between loading and storing an entity that is a sublcass of 
AbstractEntity, everything is fine. If I call the clone() method, the 
following unexpected behaviour occurs:

The PersistenceBroker inserts a new instance of AbstractEntity to the 
database (new id is used) but updates the existing instance of the 
subclass of AbstractEntity (old id is used).

To my understanding, the problem is that the id attribute is not copied 
because it is the attribute corresponding to the primary key (see 
AnonymousPersistentFieldHelper, line 98 for the reason).

Due to this situation, the PersistenceBroker creates a new database 
entry for the AbstractEntity, instead of updating the one that 
corresponds to the updated object of a subclass. Therefore, each time I 
try to update an entity that is a subclass of AbstractEntity, this 
produces an additional entry in the database table for AbstractEntity, 
instead of updating the existing one.

The "Works-for-me" solution:
============================
My proposed solution to this problem is to copy the foreign key values 
of the subclass (Car) to the primary key values of the superclass 
(AbstractEntity). In my case this means copying the value of the "id" 
attribute. Note that the id attribute is the primary key of 
AbstractEntity and Car and is used to join the tables.

Generally, copying of several foreign key attributes of the subclass to 
the primary key fields of the superclass is required (or vice-versa).

Kind regards,
   Lorenz Froihofer.

---------------------------------------------------------------------
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