You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cayenne.apache.org by Aristedes Maniatis <ar...@maniatis.org> on 2007/06/01 02:05:28 UTC

vertical inheritance joins [Was: Abstract Entities]

On 31/05/2007, at 11:46 PM, Craig L Russell wrote:

> Hi Ari,
>
> On May 31, 2007, at 12:21 AM, Aristedes Maniatis wrote:
>>
>> Then you are suggesting that we use the name of the attribute in  
>> the two ObjEntities as the mechanism to see which pairs correspond.
>
> No, I'm suggesting to look at the database schema to find the cases  
> of foreign key == primary key.
>
> And I don't think there is any need for two different fields to  
> represent the columns in the database that because of foreign key  
> constraints will always contain identical values.

Well, normally the primary key attributes are not exposed in the  
ObjEntity anyway, so I agree with what I think you are saying. But  
the question here is about compound primary keys. If we want to be  
able to support them as the basis for the join in vertical  
inheritance, then we need an objRelationship explicitly defined.



>> Well, it is a functionality decision. Do we want users to be able  
>> to delete the subclass without deleting the superclass?
>
> If this is a requirement, I'd recommend against mapping this schema  
> as inheritance. I'd map it as a one-to-zero-or-one relationship.  
> Then it's easy to delete the "subclass" instance while leaving the  
> "superclass" instance intact.

Sure, that might be the way you would want to do it, but why do we  
want to limit what others might want to do? As an example, we have in  
our current project two tables:

BinaryInfo
BinaryData

The info table contains metadata (creator, date, size, etc) and the  
data table contains just the blob (pdf, image, etc). We wanted this  
structure in separate tables so that:

* we could have different backup strategies for each
* we could optimise one table for big unindexed data
* we could put one table on a different db server, or whatever

At the moment, this is a one-one relationship, but inheritance would  
be been much nicer. We would want both classes to be concrete so that  
we could fetch binaryInfo over the network (say to display a list of  
attachments) without fetching the BLOBs. We'd also like the ability  
to 'delete' records by removing the binaryData completely and leaving  
the binaryInfo record behind with a isDeleted flag for historical  
auditing.

>
>> If the superclass is concrete why not allow that to happen? And in  
>> that case, we need to store the relationship attributes somewhere.  
>> Thankfully, we already have a mechanism to do this.
>>
>> I'm not 100% clear on what you are proposing. Is it that Cayenne  
>> should be able to construct the appropriate JOIN by looking just  
>> at the PK flag s on the attributes in question, without needing  
>> any other information stored in XML in the model? If so, why is  
>> that better than storing the (possibly redundant, but not always)  
>> information in the XML datamap file?
>
> I'm suggesting that the tool that generates the Java model from the  
> database schema should be configurable to recognize the specific  
> pattern of table2 having a primary key == foreign key to table1 and  
> generate an inheritance relationship of class2 extends class1. If  
> the requirement is to be able to independently manage instances of  
> class1 and class2, then the tool should be able to map this pattern  
> as a one-to-zero-or-one relationship.

Sure. Although I haven't been thinking of it from a reverse  
engineering perspective at all. That would be a useful extension.

> And just so it's clear, I'm not an expert in Cayenne [or EOF]. I'm  
> only offering suggestions based on a few years of doing enterprise  
> ORM.

And Cayenne's implementation will be all the better for the extra  
thinking your suggestions provoke.


> And the closer you are to being concept-compliant with JPA and JDO,  
> the more your users will be able to use other standards. Reusable  
> programmers is still a viable objective.

I agree. But at the same time, just because JPA/JDO people put a  
limitation in the specification doesn't been we have to draw the line  
there. We can always implement more functionality than is needed by  
those specs. If JPA says that the superclass is always abstract and  
we want to allow to make it concrete as an option, then more power to  
our users.


Ari Maniatis




-------------------------->
Aristedes Maniatis
phone +61 2 9660 9700
PGP fingerprint 08 57 20 4B 80 69 59 E2  A9 BF 2D 48 C2 20 0C C8



Re: vertical inheritance joins

Posted by Lachlan Deck <la...@gmail.com>.
Hi Andrus,

On 03/06/2007, at 7:12 PM, Andrus Adamchik wrote:

> On Jun 1, 2007, at 3:24 PM, Lachlan Deck wrote:
>> On 01/06/2007, at 7:32 PM, Andrus Adamchik wrote:
>>
>>> With this in mind we do not need an inheritance ObjRelationship,  
>>> but we may use a DbRelationship to store join semantics (anybody  
>>> mentioned that already??).
>>
>> Well the original suggestion I made was for <obj-entity  
>> superRelationship="nameOfRelationship" ...> to allow for  
>> specifically specifying vertical inheritance (which would have the  
>> effect of not listing this relationship along with those returned  
>> from objEntity.getRelationships() but via  
>> objEntity.getSuperRelationship().
>
> This is what I was trying to avoid - introducing relationships with  
> special behavior.

Okay. It'd be perhaps less obvious what type of inheritance was in  
play in the modeller but then again perhaps a simple dynamic label  
could display something to the same effect along with the below  
validation.

>> Are you suggesting that you'd prefer <db-entity  
>> superRelationship="nameOfRelationship" ...>
>
> No, as DbEntities (tables) do not have inheritance among  
> themselves. It would be more of <obj-entity  
> superDbRelationship="nameOfDBRelationship" ...>, but I do believe  
> that this can be made implicit, as arguably there can be only one  
> DbRelationship between the primary keys of two tables. E.g:
>
> SuperOE -> DB1
> SubOE1 -> DB2
> SubOE2 -> DB3
>
> In this case Cayenne can easily figure out the name of DB2->DB1 and  
> DB3->DB1 relationships based on relationship semantics.

Okay great. I suppose there'd need to be validation to that effect to  
ensure that such relations exist when choosing a different DbEntity  
from the parent entity.

>>> Another nice side effect of it is that such relationship is not a  
>>> part of the object model (ObjRelationship would've been an object  
>>> property). So there is nothing artificial about such mapping, and  
>>> no new concepts are needed in Cayenne to map it.
>>
>> Can you clarify this a bit more.
>
> See above - I don't want to redefine what ObjRelationship is. The  
> difference between Cayenne and EOF is that Cayenne splits DB and  
> Java mapping in two separate layers of metadata. EOF allows to mark  
> a relationship as "not included in the object model", while Cayenne  
> allows to map the DB relationship without mapping corresponding  
> ObjRelationship, essentially achieving the same thing in a  
> different way.

Thanks. Just a slight mind-shift ;-)

with regards,
--

Lachlan Deck



Re: vertical inheritance joins

Posted by Andrus Adamchik <an...@objectstyle.org>.
Hi Lachlan,

On Jun 1, 2007, at 3:24 PM, Lachlan Deck wrote:
> On 01/06/2007, at 7:32 PM, Andrus Adamchik wrote:
>
>> With this in mind we do not need an inheritance ObjRelationship,  
>> but we may use a DbRelationship to store join semantics (anybody  
>> mentioned that already??).
>
> Well the original suggestion I made was for <obj-entity  
> superRelationship="nameOfRelationship" ...> to allow for  
> specifically specifying vertical inheritance (which would have the  
> effect of not listing this relationship along with those returned  
> from objEntity.getRelationships() but via  
> objEntity.getSuperRelationship().

This is what I was trying to avoid - introducing relationships with  
special behavior.


> Are you suggesting that you'd prefer <db-entity  
> superRelationship="nameOfRelationship" ...>

No, as DbEntities (tables) do not have inheritance among themselves.  
It would be more of <obj-entity  
superDbRelationship="nameOfDBRelationship" ...>, but I do believe  
that this can be made implicit, as arguably there can be only one  
DbRelationship between the primary keys of two tables. E.g:

SuperOE -> DB1
SubOE1 -> DB2
SubOE2 -> DB3

In this case Cayenne can easily figure out the name of DB2->DB1 and  
DB3->DB1 relationships based on relationship semantics.

>> Another nice side effect of it is that such relationship is not a  
>> part of the object model (ObjRelationship would've been an object  
>> property). So there is nothing artificial about such mapping, and  
>> no new concepts are needed in Cayenne to map it.
>
> Can you clarify this a bit more.

See above - I don't want to redefine what ObjRelationship is. The  
difference between Cayenne and EOF is that Cayenne splits DB and Java  
mapping in two separate layers of metadata. EOF allows to mark a  
relationship as "not included in the object model", while Cayenne  
allows to map the DB relationship without mapping corresponding  
ObjRelationship, essentially achieving the same thing in a different  
way.

Andrus





Re: vertical inheritance joins

Posted by Lachlan Deck <la...@gmail.com>.
On 01/06/2007, at 7:32 PM, Andrus Adamchik wrote:

> With this in mind we do not need an inheritance ObjRelationship,  
> but we may use a DbRelationship to store join semantics (anybody  
> mentioned that already??).

Well the original suggestion I made was for <obj-entity  
superRelationship="nameOfRelationship" ...> to allow for specifically  
specifying vertical inheritance (which would have the effect of not  
listing this relationship along with those returned from  
objEntity.getRelationships() but via objEntity.getSuperRelationship().

Are you suggesting that you'd prefer <db-entity  
superRelationship="nameOfRelationship" ...> or just figuring out the  
relationship by finding the one that happens to map to the parent as  
a toOne?

The nice thing I thought about having a superRelationship definition  
in the modeler is that you can then make your inheritance choice in  
one place and it's clear of the choice. i.e., the above would just  
require an additional popup next to the popup for which DbEntity an  
ObjEntity maps to to choose a relationship. Otherwise perhaps it  
wouldn't be as clear whether such a relationship exists.

The other option I considered initially was having superRelationship  
as a boolean flag with validation to ensure there was an accompanying  
relationship called 'super' but thought this unnecessarily  
restrictive in the end.

> Another nice side effect of it is that such relationship is not a  
> part of the object model (ObjRelationship would've been an object  
> property). So there is nothing artificial about such mapping, and  
> no new concepts are needed in Cayenne to map it.

Can you clarify this a bit more.

Thanks.

with regards,
--

Lachlan Deck




Re: vertical inheritance joins

Posted by Andrus Adamchik <an...@objectstyle.org>.
This was a long thread, and I may have missed some points already  
made. Let me try to summarize this discussion and add my comments to  
it. There are two aspects of the "vertical inheritance relationship":

1. Specifying the join semantics for non-trivial PK-to-PK mapping  
(such as compound keys).
2. Specifying delete rules.

I am with Ari on (1) - it is in the Cayenne philosophy to map things  
explicitly, so that various weird legacy schemas can still be mapped.  
I am with Craig on (2) - if a user expects to delete a record from a  
subclass table without deleting a record in a superclass table, this  
situation should not be mapped as inheritance, as it breaks the ORM  
model at a fundamental level (an object is deleted, but some of its  
properties still remain persistent - BAD).

With this in mind we do not need an inheritance ObjRelationship, but  
we may use a DbRelationship to store join semantics (anybody  
mentioned that already??). Another nice side effect of it is that  
such relationship is not a part of the object model (ObjRelationship  
would've been an object property). So there is nothing artificial  
about such mapping, and no new concepts are needed in Cayenne to map it.

Andrus