-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 38 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject: Can not remove object from Set (equals & hash are correc
PostPosted: Sat Nov 13, 2004 10:24 pm 
Newbie

Joined: Mon Sep 06, 2004 10:38 pm
Posts: 8
Hibernate version: 2.1.6

Hello all.

In my application I over-ride equals & hashCode properly. When I add instances of these classes to Vector's and call remove(), equals() gets called and the object is removed as it should be (if equals == true). However, when I call remove() on a persistable set, equals() is never called, and the object is not removed.

I've tried several different things, all to no avail. I have tried debugging, and have even added the following block to my equals() method:

System.out.println("equals() called:");
System.out.println(" myself == " + this);
System.out.println(" other == " + object);
System.out.println(" returning: " + isEquals);
System.out.println(" stack: " );
new Throwable().printStackTrace();


when I then call:
persistent.getPersistentSet().remove(otherPersistent)
the above print block never is executed.


When I call vector.remove(otherPersistent)
it is.

Any ideas of where to look further? Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Nov 14, 2004 8:30 pm 
Newbie

Joined: Thu Sep 09, 2004 6:50 am
Posts: 15
check your comparator. it seems the collections used by hibernate look for the comparator==0 to check equality


Top
 Profile  
 
 Post subject: How do we specify a comparator?
PostPosted: Sat Dec 18, 2004 2:22 pm 
Newbie

Joined: Sat Dec 18, 2004 2:17 pm
Posts: 19
maulinshah wrote:
check your comparator. it seems the collections used by hibernate look for the comparator==0 to check equality


I have the same problem (2.1.7), although it looks like equals() is being called and ignored. I've implemented Comparable on my persistable class, but I'm still failing to delete an object from a Collection.

I can easily implement a suitable Comparator, but how do I tell the system to use it for this class? I checked the API but the Set comparator doesn't appear to take an optional Comparator parameter.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Dec 18, 2004 4:20 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
hmm - this smells ;)

first - you mention Vector which is not part of the Java 2 Collection API and as such is not something persistable with hibernate.

Secondly, have you tried doing this in a simple unit test where you just use the normal java API (no hibernate) to rule out any thing wrong with the equals/hashcode ?

You say you tried testing by inserting stuff into equals, and says that it is never called....please know that equals wont be called in most sets if its hashcodes doesn't say two objects has the same hashcode.

...i'm quite sure you have some error in your hashcode impl based on your information.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Sat Dec 18, 2004 4:24 pm 
Newbie

Joined: Mon Sep 06, 2004 10:38 pm
Posts: 8
The vector was not persistent; it just contained persistent elements. The problem did seem to be fixed with a different implementation of hashCode().

The one I had been using was from the Jakarta Commons, which sucked!


Top
 Profile  
 
 Post subject:
PostPosted: Sat Dec 18, 2004 4:27 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
well - not that i want to praise the wonders of jakarta commons, then i'm quite sure that it was you who defined which properties it would use to make the hashcode from, correct ? ;)

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Sat Dec 18, 2004 6:16 pm 
Newbie

Joined: Sat Dec 18, 2004 2:17 pm
Posts: 19
I'm having problems with the Set returned from my Hibernate class. I've verified that the object is a net.sf.hibernate.collection.Set.

My Comparable persistent element has hashCode(), equals() and comparable() instrumented. All report when they're called, hashCode() also reports the hash code.

My unit tests include:
Code:
    Parent parent = new Parent();
    Child child1 = getSampleChild(parent);
    Child child2 = getSampleChild(parent);
    Child child3 = getSampleChild(parent);
    child.setName("edgar");

    assertTrue(child1.equals(child1));
    assertTrue(child1.equals(child2));
    assertFalse(child1.equals(child3));

which succeeds, but a similar test that adds
Code:
    ParentManager mgr = (ParentManager) getManager("parentManager");
    mgr.saveParent(parent);

    // test for all children were persisted... succeeds
    // iterate through set calling equals() and compareTo() for
    // each element against "child3" - results as expected.

    assertTrue(parent.getChildren().contains(child1));

an exception is thrown. Neither equals() nor compareTo() is called. A related test that replaces the final line with
Code:
    Long id = child1.getId();
    parent.getChildren().remove(child1);

    ChildManager cmgr = (ChildManager) getManager("childManager");
    try {
       Child child = cmgr.getChild(id);
        fail("deleted object still exists in database!");
    catch (Exception e) {
        log.debug("caught expected exception");
    }

also fails. From other instrumentation I know that the 'remove' call did not remove the element from the set.

And covering all f the bases, I've verified that the elements are exactly the same -- they have the same address. There's absolutely no way any sane equals() or compareTo() method would not recognize the parameter and set element as identical.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Dec 18, 2004 6:21 pm 
Newbie

Joined: Sat Dec 18, 2004 2:17 pm
Posts: 19
Oops, you proofread something three times and still miss something....

[quote="kokopelli"]
Code:
    Long id = child1.getId();
    parent.getChildren().remove(child1);
   
    // persist parent, should delete child with 'all-delete-orphan'
    mgr.saveParent(parent);

    ChildManager cmgr = (ChildManager) getManager("childManager");
    try {
       Child child = cmgr.getChild(id);
        fail("deleted object still exists in database!");
    catch (Exception e) {
        log.debug("caught expected exception");
    }


Top
 Profile  
 
 Post subject:
PostPosted: Sun Dec 19, 2004 6:38 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
dude - you code doesnt prove anything else that you have a faulty equals, hashcode and/or compareto.

So, why not show those also ?

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Sun Dec 19, 2004 7:42 pm 
Newbie

Joined: Sat Dec 18, 2004 2:17 pm
Posts: 19
max wrote:
dude - you code doesnt prove anything else that you have a faulty equals, hashcode and/or compareto.

So, why not show those also ?


1) the unit tests (including some not shown) show no problems with these methods.

2) by definition x.equals(x) must be true, my equals() and compareTo() method check this explicitly, and I mentioned earlier that I've verified that an object in the collection and the object being removed are identical. Not "equal", a single object.

3) even if my implementation is faulty, it's a moot point since none of these methods is being called on a "contains" or "remove" call according to the logging statement at the top of the method.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Dec 19, 2004 8:57 pm 
Newbie

Joined: Sat Dec 18, 2004 2:17 pm
Posts: 19
I've been doing some additional research. I can't figure out where the hibernate code gets the implementing Set. Not net.sf.hibernate.collection.Set, but the private set it wraps. If nothing else I thought that would give me insight into exactly how contains() and remove() are implemented.

As for the earlier suggestion that the implementation uses a Comparator, or at least the compareTo method (which is defined in Comparable, not Comparator), the Sun J2SE documentation for java.util.Set.contains() says:

Quote:
Returns true if this set contains the specified element. More formally, returns true if and only if this set contains an element e such that (o==null ? e==null : o.equals(e)).


which means that the implementation (wherever it is) shouldn't be using "compareTo() == 0" instead of "equals()" anyway. This is doubly true because the java.lang.Comparable contract says:

Quote:
The natural ordering for a class C is said to be consistent with equals if and only if (e1.compareTo((Object)e2) == 0) has the same boolean value as e1.equals((Object)e2) for every e1 and e2 of class C.

It is strongly recommended (though not required) that natural orderings be consistent with equals. This is so because sorted sets (and sorted maps) without explicit comparators behave "strangely" when they are used with elements (or keys) whose natural ordering is inconsistent with equals. In particular, such a sorted set (or sorted map) violates the general contract for set (or map), which is defined in terms of the equals method.


My class has consistent behavior.


P.S., I don't think I mentioned it upstream but in one of my unit tests I do the same test described above but after persisting my test object I create my own set via "new HashSet(parent.getChildren())" and everything succeeds against that set. This is why I am extremely skeptical that the problem is in my hashCode() or equals() methods.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Dec 19, 2004 9:21 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
OK, time to stop blaming other people for your problems, and start from the assumption that it is your own code at fault. Of course there is no bug in Hibernate in this incredibly well-tested functionality, which is in use in thousands of production systems.

Regarding compareTo(), it is not used unless you have a sorted set (of course).

Regarding the code samples you show, they are useless.

Regarding how to find a solution to your problem: use your debugger. Step into Set.remove(), it should be very simple to understand what is going wrong.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Dec 19, 2004 10:09 pm 
Newbie

Joined: Sat Dec 18, 2004 2:17 pm
Posts: 19
gavin wrote:
OK, time to stop blaming other people for your problems, and start from the assumption that it is your own code at fault. Of course there is no bug in Hibernate in this incredibly well-tested functionality, which is in use in thousands of production systems.


Please tell me where I'm blaming others, Gavin.

Please tell me where I said the problem is in the Hibernate code.

I've never said either. I reported a repeatable problem and every test I've done to rule out my code as a culprit. When unit tests on equals(), compareTo() and using HashSet() say everything is fine in my code I have a hard time swallowing the "it's your own code, moron" line.

Is it in the Hibernate code? I doubt it and I never pointed my finger in that direction. I assumed I overlooked something in the documentation or it's something in my environment. I was reporting a problem in the hopes that somebody else had seen similiar behavior and identified a fix. Max is the one who started pissing on my code, perhaps because he confused me with the earlier poster, and that's probably why you think I'm pissing on hibernate.

P.S., I never use a debugger into third party code. In my experience this inevitably leads to fragile code because it leads to the perceived problem being fixed, not the real one. That's why I tried to find the implementing class this afternoon. Perhaps you can tell me which file that is....

Meanwhile I have to get back to writing a trivial parent/child class so that I can either rule out my environment (if it works) or publish for others to test on their system (if it fails).


Top
 Profile  
 
 Post subject:
PostPosted: Sun Dec 19, 2004 10:49 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Fair enough. I assumed that the reason you were quoting the JavaDoc for Set at us was that you thought we didn't know what it said.

I don't understand your comment about never stepping into 3rd party libraries. wtf? The great benefit of Hibernate being open source is that you can see what is going on when things go wrong. You will waste everyone's time if you don't take advantage of this.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 20, 2004 12:33 am 
Newbie

Joined: Sat Dec 18, 2004 2:17 pm
Posts: 19
gavin wrote:
Fair enough. I assumed that the reason you were quoting the JavaDoc for Set at us was that you thought we didn't know what it said.


There was a suggestion earlier that the 'many' side of the relationship needed to implement the Comparator class (or Comparable interface) because the collections used compareTo() == 0 instead of equals(). This suggestion that was never shot down. I was commenting, for the record, that that couldn't be the case. I apologize if I gave the impression that I believed this was the cause of my problem - it's been a very long three days. :-(

gavin wrote:
I don't understand your comment about never stepping into 3rd party libraries. wtf? The great benefit of Hibernate being open source is that you can see what is going on when things go wrong. You will waste everyone's time if you don't take advantage of this.


I look at the source all the time, but in that case I can get enough context to be sure I understand the problem. You don't get that with a debugger - you might misidentify where the problem occurs, etc. What's scary is that "fixes" based on incomplete information often work... for awhile.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 38 posts ]  Go to page 1, 2, 3  Next

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.