Spring Data Neo4j
  1. Spring Data Neo4j
  2. DATAGRAPH-265

ManagedFieldAccessorSet does not follow Set contract (with remove(obj) for example)

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 2.1.RC1
    • Fix Version/s: None
    • Component/s: None
    • Labels:
      None

      Description

      I use simple mapping. I have a husband entity containing Set of Child entities.

       
      @NodeEntity
      public class Husband {
          @GraphId
          private Long graphId;
          private String name;
          @RelatedTo(type = "has_child", direction = Direction.OUTGOING)
          private Set<Child> children = new HashSet<Child>();
      ...
      

      And Child entity:

       
      @NodeEntity
      public class Child {
          @GraphId
          private Long graphId;
          private String name;
      ...
      

      Child entity override equals/hashCode, taking nullable "graphId" and "name" into account.

      Inside transactional action, removing Child entity from parent Husband entity doesn't work via set.remove(obj), although set.contains(obj) returns true. More concretely,

      children.contains(child) == true
      but
      children.remove(child) == false

      When I drill into the matter, I discovered something strange. Inside ManagedFieldAccessorSet's remove method, you pass the call to delegate Set:

       
          public boolean remove(Object o) {
              if (delegate.remove(o)) {
                  update();
                  return true;
              }
              return false;
          }
      

      Strange thing is that my debugger shows that delegate field is plain java.util.HashSet containing the exact instance of element that I'm trying to remove ("o" parameter in remove method), but nonetheless it cannot find it inside to remove it. I tried executing contains method while debugging, and it cannot find the element also:
      delegate.contains(o) = false
      Really strange!
      But, when I try inside my debugger to copy first the contents of delegate set to my new one, and check the existence of the element, it works then. In other words:
      new HashSet(delegate).contains(o) = true

      Like delegate is some strange Set impl, but my debugger shows its just plain java.util.HashSet.

        Activity

        Hide
        Mark Spritzler added a comment -

        This is just like my Jira DATAGRPAH-267. Maybe we should connect them, make this the one, since it was created before.

        Mark

        Show
        Mark Spritzler added a comment - This is just like my Jira DATAGRPAH-267. Maybe we should connect them, make this the one, since it was created before. Mark
        Hide
        Vjeran Marcinko added a comment -

        I think the title is not hitting the spot. I think the crux of the problem is that equals/hashCode must not change once it ended up in HashSet. As I mentioned on the forum, I only see that natural key should be used inside equals/hashCode, not graph ID, since one can work with domain objects outside of db transaction (like unit tests), and even when used in transaction, if we use only graph ID, then one fill some HashSet collection with several objects isnide one transaction before they are saved, so HashSet would not recognize these as different objects sicne they all still have their graph ID null.

        Show
        Vjeran Marcinko added a comment - I think the title is not hitting the spot. I think the crux of the problem is that equals/hashCode must not change once it ended up in HashSet. As I mentioned on the forum, I only see that natural key should be used inside equals/hashCode, not graph ID, since one can work with domain objects outside of db transaction (like unit tests), and even when used in transaction, if we use only graph ID, then one fill some HashSet collection with several objects isnide one transaction before they are saved, so HashSet would not recognize these as different objects sicne they all still have their graph ID null.

          People

          • Assignee:
            Michael Hunger
            Reporter:
            Vjeran Marcinko
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated: