On 3/29/08 6:15 AM, "Andrus Adamchik" <andru..bjectstyle.org> wrote:
>> I think that part of the issue is that Cayenne seems to be
>> inconsistent in
>> how it handles this.
>>
>> A runtime relationship is not created if a subclass is missing a
>> relationship. ObjEntity will try to use the base class's
>> relationship if it
>> can.
>
> Why is that inconsistent? ObjEntity is a model of a Java class... All
> superclass fields and methods are first-class citizens (no pun
> intended) in a subclass... So a relationship owned by a superentity,
> is a relationship of every subentity. This logic of course applies to
> the *source* of the relationship, not the *target* (there is no
> relationship target inheritance). Or are you talking about something
> else?
I may very well be getting confused, but this is what I'm seeing:
sub.setToRelatedEntity(related);
This retrieves the relationship from BaseEntity to RelatedEntity. Some key
fields are:
dbRelationshipPath: relatedEntities
name: toRelatedEntity
sourceEntity: BaseEntity
targetEntityName: RelatedEntity
Now, there really are two candidate reverse relationships, depending on what
class it's being called from:
RelatedEntity -> BaseEntity:
dbRelationshipPath: entities
name: baseEntities
sourceEntity: RelatedEntity
targetEntityName: BaseEntity
and
RelatedEntity -> SubEntity:
dbRelationshipPath: entities
name: subEntities
sourceEntity: RelatedEntity
targetEntityName: SubEntity
What I'm seeing is one relationship being the reverse for two others. This
isn't readily apparent because the following line in
ObjRelationship#getReverseRelationship() stops any sort of polymorphism from
occurring:
if (rel.getTargetEntity() != src)
continue;
In this case, the src is always "BaseEntity" so the RelatedEntity ->
BaseEntity relationship is the one that's found and used. If that check is
removed, then both candidate relationships are found, but now we have an
issue of ambiguity.
What my previous notes indicate is that if instead of using the inherited
relationship with the base type set as the sourceEntity, we create a new
relationship for the subEntity using it as the sourceEntity value, the
previous check can stick. In this way, we'll always find the most specific
rather than the most general relationship. It does not serve to address the
fact of updating all parents, but I contend that it is easier to work bottom
up than top down, due to the unambiguous path that must be taken from a
subclass through all of its ancestors.
Essentially, what I'm seeing is that there is not a 1:1 correlation between
relationships and their reverses. Moreover, the calculation of reverse
relationship makes the distinction between source and target entities murky,
since the roles can swap quite easily, so relying on Java inheritance in one
case and independent relationships in another can be problematic.
Even if I'm still wrong, I hope this clarifies more, especially with regards
to why I feel like that conditional check is problematic. I've voiced that
in the past while looking at this issue and it just feels wrong to me.
Regards,
Kevin
This archive was generated by hypermail 2.0.0 : Sat Mar 29 2008 - 09:17:34 EDT