-->
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.  [ 9 posts ] 
Author Message
 Post subject: remove(..) problem
PostPosted: Wed Oct 12, 2005 5:43 am 
Newbie

Joined: Wed Oct 12, 2005 4:54 am
Posts: 9
Hibernate version:3.1 rc1 (problem also occured in 3.0.5)

Hallo,

after searching through this and the german hibernate forum, I decided to post a question by myself.

I never saw a likewise problem, so I strongly suggest that I've done anything wrong. But I also can't find the point of failure.

Description: A Person(one) has Addresses(many) [in hibernate bidirectionally linked]; if a Person entity is deleted, all regarding adresses will be deleted too (cascade)...so long so good
The thing I want to do is to simply delete an address-entity of a person.
Because of cascading I just don't have to delete the address-entity, but also need to delete the regarding address-objekt from the address-list of person. And that's exactly the problem.

Code:
Adr adr;
boolean b;
...

b = adr.getPerson().getAdrSet().remove(adr);
// b:false


means, adr won't be delete from the Set (confirmed by .size() ), although

Code:
Iterator it =adr.getPerson().getAdrSet().iterator();
while (it.hasNext()) {
   Adr adr2 = (Adr) it.next();
   if (adr2.equals(adr)) {
      b=true;
                //it.remove();    even this doesn't work
      break;
   }
}//while
//b:true ...object was really found but not deleted


May be this has something to do with the implemented equals and hashCode methods?! There were generated by MyEclipse-HibernatePlugin:

(Example Adr)
Code:

    public boolean equals(Object rhs)
    {
        if (rhs == null)
            return false;
        if (! (rhs instanceof Adr))
            return false;
        Adr that = (Adr) rhs;
        if (this.getAdrId() == null || that.getAdrId() == null)
            return false;
        return (this.getAdrId().equals(that.getAdrId()));
    }

    public int hashCode()
    {
        if (this.hashValue == 0)
        {
            int result = 17;
            int adrIdValue = this.getAdrId() == null ? 0 : this.getAdrId().hashCode();
            result = result * 37 + adrIdValue;
            this.hashValue = result;
        }
        return this.hashValue;
    }


please help me blowing away the fog of nescience.

Thnx in advance

Btw: Hibernate is impressive


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 12, 2005 10:30 am 
Expert
Expert

Joined: Sat Jan 17, 2004 2:57 pm
Posts: 329
Location: In the basement in my underwear
sjtuner,

your problem is exactly as you guessed it. Your hashcode and equals is based on your PK and if that changes, i.e. the object is saved, after you place your objects in a set you will never be able to find it again with remove() or contains() and in fact, add() will produce a 'duplicate'.

Take a look at
http://www.hibernate.org/109.html

I would suspect that your call to remove returns false (there is a boolean returned that you can double check). When adding an object to a HashSet the added object is keyed off it's initial hashcode state. If the key changes you'll never be able to find it normally in a set anymore. Although, the it.remove() should have removed the element IIRC.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 12, 2005 10:59 am 
Newbie

Joined: Wed Oct 12, 2005 4:54 am
Posts: 9
I understood your arguments, but what is, if the PK hasn't changed and even the hashCode() method deliveres the same value.
Then that's the case :-(

I know, a very strange case!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 12, 2005 12:57 pm 
Expert
Expert

Joined: Sat Jan 17, 2004 2:57 pm
Posts: 329
Location: In the basement in my underwear
So, when you add the object to your set your key is already defined?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 12, 2005 2:15 pm 
Newbie

Joined: Wed Oct 12, 2005 4:54 am
Posts: 9
No it isn't. As you rightfully guess, at first I add a new address-object to a new person-object and then I persist person to the db.

But I System.out.println'ed all attributes (inkl. PK) of both(adr, adr2) objects to console and both are similar.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 12, 2005 3:08 pm 
Expert
Expert

Joined: Sat Jan 17, 2004 2:57 pm
Posts: 329
Location: In the basement in my underwear
The tricky part is that when you add your objects to a set then they are keyed off of the unsaved object's hashcode. Once you save the object and if the hashcode changes then you won't find it in the HashSet.

If you iterate through the set and spit out the hashcodes they WILL match; however, the key is still the old value. But you'll never find it with remove() or contains().


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 13, 2005 2:53 am 
Newbie

Joined: Wed Oct 12, 2005 4:54 am
Posts: 9
I checked this and you're right!

Thank you very much. I'm going to kind of upgrade my equals and hashCode methods.
At least for the equals method I got something in my mind(compare business keys). Do you have any ideas for the hashCode-Method?

Best regards


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 13, 2005 3:03 am 
Newbie

Joined: Wed Oct 12, 2005 4:54 am
Posts: 9
...and do you meanwhile have any explanation, why the it.remove() statement doesn't work? (see code in first post)


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 13, 2005 3:40 am 
Newbie

Joined: Wed Oct 12, 2005 4:54 am
Posts: 9
found an appropriate article :)

Thnx for your help


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 

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.