FAQ
Reverse relationships may not be correctly set if inheritance is used.
----------------------------------------------------------------------

Key: CAY-1008
URL: https://issues.apache.org/cayenne/browse/CAY-1008
Project: Cayenne
Issue Type: Bug
Components: Cayenne Core Library
Affects Versions: 3.0
Reporter: Kevin Menard
Assignee: Andrus Adamchik


Given two entities, Employee and Address, such that there is a one-to-many relationship between the two, it may be possible that reverse relationships are not fully set if inheritance is used.

For example, let's say that HomeAddress extends Address, then the following fails:

Employee e = context.newObject(Employee.class);

Address a = context.newObject(Address.class);
a.setToEmployee(e);

assertEquals(1, e.getAddresses().size());
assertEquals(0, e.getHomeAddresses().size());

HomeAddress ha = context.newObject(HomeAddress.class);
ha.setToEmployee(e);

assertEquals(2, e.getAddresses().size());
assertEquals(1, e.getHomeAddresses().size());

The last assertion fails as e.getHomeAddresses() will return an empty list.

On the face of it, the problem is that the ObjRel "addresses" is being set rather than "homeAddresses". This is due to how ObjRelationship#getReverseRelationship() determines reverse relationships. It does so by inspecting the relationship structure and if there's a match, returns it. "addresses" and "homeAddresses" have the same structure and "addresses" is the first match found and returned.

Simply reversing order or other similar tricks won't really do anything more for us though. The real issue seems to be how to deal with multiple ObjRels that match to the same DbRel. Each ObjRel does need to be updated in order for the graph to remain consistent.

--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Search Discussions

  • Anonymous at Jun 2, 2008 at 7:34 pm
    [ https://issues.apache.org/cayenne/browse/CAY-1008?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12894#action_12894 ]

    Robert Zeigler commented on CAY-1008:
    -------------------------------------

    Turns out you don't even need inheritance to see this bug.
    I duplicated this today with the following mapping:

    db relationship:
    artist -> paintings (one to many)

    obj relationships:
    artist.paintingList maps via the artist->paintings relationship as a java.util.List
    artist.paintingsByTitle maps via the artist->paintings relationship as a java.util.Map, keyed on the painting title.

    Artist a = context.newObject(Artist.class);
    a.setName("Test Artist");
    context.commitChanges();
    assertEquals(a.getPaintingList().size(),0);
    assertEquals(a.getPaintingsByTitle().size(),0);//"A"
    Painting p = new Painting();
    p.setPrice(10.0);
    p.setTitle("Test Painting");
    p.setArtist(a);
    context.commitChanges();
    assertEquals(a.getPaintingList().size(),1);
    assertEquals(a.getPaintingsByTitle().size(),1);//"B"

    context.deleteObject(p);
    context.commitChanges();
    assertEquals(a.getPaintingList().size(),0);
    assertEquals(a.getPaintingsByTitle().size(),0);//"C"


    If you leave the line labeled "A" in place, then "B" will fail. If you comment out "A", "B" will pass (because the list won't be resolved until that point, so it will be resolved from the database, I'm presuming). If you comment out "A", but leave "B" and "C", then C will fail (size will be 1). If you comment out "A" and "B", then "C" passes.

    I can slim down the mapping info and attach it, if that would be helpful.
    Reverse relationships may not be correctly set if inheritance is used.
    ----------------------------------------------------------------------

    Key: CAY-1008
    URL: https://issues.apache.org/cayenne/browse/CAY-1008
    Project: Cayenne
    Issue Type: Bug
    Components: Cayenne Core Library
    Affects Versions: 3.0
    Reporter: Kevin Menard
    Assignee: Andrus Adamchik

    Given two entities, Employee and Address, such that there is a one-to-many relationship between the two, it may be possible that reverse relationships are not fully set if inheritance is used.
    For example, let's say that HomeAddress extends Address, then the following fails:
    Employee e = context.newObject(Employee.class);
    Address a = context.newObject(Address.class);
    a.setToEmployee(e);
    assertEquals(1, e.getAddresses().size());
    assertEquals(0, e.getHomeAddresses().size());
    HomeAddress ha = context.newObject(HomeAddress.class);
    ha.setToEmployee(e);
    assertEquals(2, e.getAddresses().size());
    assertEquals(1, e.getHomeAddresses().size());
    The last assertion fails as e.getHomeAddresses() will return an empty list.
    On the face of it, the problem is that the ObjRel "addresses" is being set rather than "homeAddresses". This is due to how ObjRelationship#getReverseRelationship() determines reverse relationships. It does so by inspecting the relationship structure and if there's a match, returns it. "addresses" and "homeAddresses" have the same structure and "addresses" is the first match found and returned.
    Simply reversing order or other similar tricks won't really do anything more for us though. The real issue seems to be how to deal with multiple ObjRels that match to the same DbRel. Each ObjRel does need to be updated in order for the graph to remain consistent.
    --
    This message is automatically generated by JIRA.
    -
    You can reply to this email to add a comment to the issue online.
  • Anonymous at Jun 2, 2008 at 7:45 pm
    [ https://issues.apache.org/cayenne/browse/CAY-1008?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12895#action_12895 ]

    Andrus Adamchik commented on CAY-1008:
    --------------------------------------

    The example is clear. This is what I called "redundant" relationships in our mailing list discussion that followed from the related set of Jiras including this one. (I don't remember what we decided to call "redundant" to avoid implying a negative meaning)... Anyways, Cayenne will not maintain the object graph consistency if there are multiple relationships between 2 entities, spanning the same set of joins. Right now that's more of a "feature" than a "bug" IMO (ok, maybe a "limitation" coming from the fact that the authors originally didn't find use for such relatinships themselves), but we can impement an algorithm that will handle such case as well.
    Reverse relationships may not be correctly set if inheritance is used.
    ----------------------------------------------------------------------

    Key: CAY-1008
    URL: https://issues.apache.org/cayenne/browse/CAY-1008
    Project: Cayenne
    Issue Type: Bug
    Components: Cayenne Core Library
    Affects Versions: 3.0
    Reporter: Kevin Menard
    Assignee: Andrus Adamchik

    Given two entities, Employee and Address, such that there is a one-to-many relationship between the two, it may be possible that reverse relationships are not fully set if inheritance is used.
    For example, let's say that HomeAddress extends Address, then the following fails:
    Employee e = context.newObject(Employee.class);
    Address a = context.newObject(Address.class);
    a.setToEmployee(e);
    assertEquals(1, e.getAddresses().size());
    assertEquals(0, e.getHomeAddresses().size());
    HomeAddress ha = context.newObject(HomeAddress.class);
    ha.setToEmployee(e);
    assertEquals(2, e.getAddresses().size());
    assertEquals(1, e.getHomeAddresses().size());
    The last assertion fails as e.getHomeAddresses() will return an empty list.
    On the face of it, the problem is that the ObjRel "addresses" is being set rather than "homeAddresses". This is due to how ObjRelationship#getReverseRelationship() determines reverse relationships. It does so by inspecting the relationship structure and if there's a match, returns it. "addresses" and "homeAddresses" have the same structure and "addresses" is the first match found and returned.
    Simply reversing order or other similar tricks won't really do anything more for us though. The real issue seems to be how to deal with multiple ObjRels that match to the same DbRel. Each ObjRel does need to be updated in order for the graph to remain consistent.
    --
    This message is automatically generated by JIRA.
    -
    You can reply to this email to add a comment to the issue online.
  • Anonymous at Jun 2, 2008 at 8:06 pm
    [ https://issues.apache.org/cayenne/browse/CAY-1008?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12896#action_12896 ]

    Robert Zeigler commented on CAY-1008:
    -------------------------------------

    I think you're right that "limitation" is right word. From a "naive user" perspective, however, it "feels like" a bug, since object-graph consistency is nicely handled, and then you add that second object relationship, and, hey, my object graph isn't consistent anymore.

    Depending on my time, I may take a shot at patching this. We'll see.
    Reverse relationships may not be correctly set if inheritance is used.
    ----------------------------------------------------------------------

    Key: CAY-1008
    URL: https://issues.apache.org/cayenne/browse/CAY-1008
    Project: Cayenne
    Issue Type: Bug
    Components: Cayenne Core Library
    Affects Versions: 3.0
    Reporter: Kevin Menard
    Assignee: Andrus Adamchik

    Given two entities, Employee and Address, such that there is a one-to-many relationship between the two, it may be possible that reverse relationships are not fully set if inheritance is used.
    For example, let's say that HomeAddress extends Address, then the following fails:
    Employee e = context.newObject(Employee.class);
    Address a = context.newObject(Address.class);
    a.setToEmployee(e);
    assertEquals(1, e.getAddresses().size());
    assertEquals(0, e.getHomeAddresses().size());
    HomeAddress ha = context.newObject(HomeAddress.class);
    ha.setToEmployee(e);
    assertEquals(2, e.getAddresses().size());
    assertEquals(1, e.getHomeAddresses().size());
    The last assertion fails as e.getHomeAddresses() will return an empty list.
    On the face of it, the problem is that the ObjRel "addresses" is being set rather than "homeAddresses". This is due to how ObjRelationship#getReverseRelationship() determines reverse relationships. It does so by inspecting the relationship structure and if there's a match, returns it. "addresses" and "homeAddresses" have the same structure and "addresses" is the first match found and returned.
    Simply reversing order or other similar tricks won't really do anything more for us though. The real issue seems to be how to deal with multiple ObjRels that match to the same DbRel. Each ObjRel does need to be updated in order for the graph to remain consistent.
    --
    This message is automatically generated by JIRA.
    -
    You can reply to this email to add a comment to the issue online.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupdev @
categoriescayenne
postedMar 13, '08 at 8:17p
activeJun 2, '08 at 8:06p
posts4
users1
websitecayenne.apache.org

1 user in discussion

Anonymous: 4 posts

People

Translate

site design / logo © 2022 Grokbase