Re: Cleaning up inheritance tests

From: Kevin Menard (kmenar..ervprise.com)
Date: Sat Mar 29 2008 - 09:16:58 EDT

  • Next message: Andrus Adamchik: "Re: Cleaning up inheritance tests"

    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