Let me propose for implementation a new Cayenne feature that seems useful and interesting and arises from the needs of the project I am working on. Please give your comments.
Assume, we have two tables and a relationship between them defined as follows:
CREATE TABLE PRIMARY_TABLE (
PRIMARY_TABLE_ID INTEGER NOT NULL,
NAME VARCHAR(32) NOT NULL,
CONSTRAINT PRIMARY_TABLE_PK PRIMARY KEY ( PRIMARY_TABLE_ID )
) ;
CREATE TABLE DEPENDENT_TABLE (
DEPENDENT_TABLE_ID INTEGER NOT NULL,
DESC VARCHAR(32) NOT NULL,
CONSTRAINT DEPENDENT_TABLE_PK PRIMARY KEY ( DEPENDENT_TABLE_ID )
) ;
ALTER TABLE DEPENDENT_TABLE ADD CONSTRAINT PRIMARY_TABLE_FK
FOREIGN KEY (DEPENDENT_TABLE_ID)
REFERENCES PRIMARY_TABLE (PRIMARY_TABLE_ID) ;
In this case DEPENDENT_TABLE completely depends on PRIMARY_TABLE and we can look at them as a single entity. Indeed, it is a one-to-one relationship and each record in their join will uniquely be identified by PRIMARY_TABLE_ID. For us it means the opportunity to introduce a notion of ObjEntity spanning the join of these tables. If we support such ObjEntities we can take advantage of persistent inheritance for DataObjects.
For example, we define
class PrimaryTableDataObject extends CayenneDataObject
This class will be persisted in PRIMARY_TABLE and the corresponding ObjEntity will be PrimaryTable backed up by the DbEntity PRIMARY_TABLE.
Now we can extend it:
class SubDataObject extends PrimaryTableDataObject
This class will make use of both PRIMARY_TABLE and DEPENDENT_TABLE to store its attributes and its ObjEntity will relate to the PRIMARY_TABLE and DEPENDENT_TABLE DbEntities at the same time.
For a Cayenne user it will be true extension as ObjectId is not changed and SubDataObject still behaves like PrimaryTableDataObject does but some new attributes are added. For the Cayenne internals, conceptually, it will mean two inserts, updates, deletes and slightly more complex selects per object, nothing more, seemingly, because we still have one primary DbEntity and primary key to rely upon. Additional tables may be of the kind mentioned above only. In a data map this configuration may be described as below:
<!ELEMENT obj-entity (dependent-db-entity*, obj-attribute+)>
<!ATTLIST obj-entity
name CDATA #REQUIRED
className CDATA #REQUIRED
dbEntityName CDATA #REQUIRED
superClassName CDATA #IMPLIED
readOnly (true | false) "false"
>
<!ELEMENT obj-attribute EMPTY>
<!ATTLIST obj-attribute
name CDATA #REQUIRED
db-attribute-name CDATA #REQUIRED
db-entity-name CDATA #IMPLIED
type CDATA #REQUIRED
>
<!ELEMENT dependent-db-entity EMPTY>
<!ATTLIST dependent-db-entity
name CDATA #REQUIRED
>
As you see a new element dependent-db-entity is added and obj-attribute will bear an additional optional attribute db-entity-name. If it is empty dbEntityName will default otherwise it must point to one of the dependent-db-entity -es referenced in this obj-entity.
This feature is, in fact, very much like the concept of flattened relationships, only a DbRelationship is hidden inside an ObjEntity.
Andriy.
This archive was generated by hypermail 2.0.0 : Thu Feb 27 2003 - 11:43:14 EST