-->
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.  [ 4 posts ] 
Author Message
 Post subject: PersistentSet duplicates objs
PostPosted: Wed Jul 25, 2007 2:53 pm 
Beginner
Beginner

Joined: Sat Jul 29, 2006 12:29 am
Posts: 27
Hi,

I've got same problem as here (http://forum.hibernate.org/posting.php? ... y&t=965543). After persist a Set inside my graph, i sucessfully tried to add a repeated State (same name) into a detached Country.

I'm a beginner and I'm keen to understand this behavior.

Hibernate Log

14:42:10,796 INFO Version:15 - Hibernate EntityManager 3.2.1.GA
14:42:10,828 INFO Version:15 - Hibernate Annotations 3.2.1.GA
14:42:10,843 INFO Environment:514 - Hibernate 3.2.4.sp1
14:42:10,843 INFO Environment:547 - hibernate.properties not found
14:42:10,843 INFO Environment:681 - Bytecode provider name : cglib
14:42:10,859 INFO Environment:598 - using JDK 1.4 java.sql.Timestamp handling


Code:

public class Country implements Serializable {

    @Id @GeneratedValue
    private Long id;
   
    private String name;
   
    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name="idCountry")
    private Set<Country> countries = new HashSet<Country>();

......

        public void addState(State state) {
      if (!this.getStates().add(state)){
         throw new BusinessException("State exists");
      }

   public int hashcode() {
      return 29 * getNome().hashCode();
   }
   
   public boolean equals(Object o) {
      if (this == o) return true;
      if (!(o instanceof Pais)) return false;

      final Pais pais = (Pais) o;

      if (!nome.equals(pais.getNome())) return false;
      return true;
   }
   

    }


Code:
public class UnidadeFederativa implements Serializable {

    @Id @GeneratedValue
    private Long id;

    private String name;
   
    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name="idState")
    private Set<City> city = new HashSet<City>();

   public int hashcode() {
      return 29 * getNome().hashCode();
   }
   
   public boolean equals(Object o) {
      if (this == o) return true;
      if (!(o instanceof State)) return false;

      final State state = (State) o;

      if (!name.equals(state.name)) return false;
      
      return true;
   }



1) It seems PersistentSet isn't using equals() when it gets "if (!this.getStates().add(state))". Is it true?

2) I've understood that if I had used ID in equals/hashcode it would be the cause of the problems. But I'm not using ID on equals/hashcode. I've read this article (http://www.hibernate.org/109.html) and thought that implementations with business keys shouldn't get problems.

3) How can I solve this issue!? I have also tried with refresh/flush inside session but without sucess.

Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 25, 2007 11:49 pm 
Senior
Senior

Joined: Sat Aug 19, 2006 6:31 pm
Posts: 139
Can you share the equals() and hashCode() method for State?

On your Country and UnidadeFederative class, the the hashcode() function uses lowercase c. Those really should be uppercase. Maybe your state class has the same problem?

_________________
Don't forget to rate the reply if it helps..:)

Budyanto


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 26, 2007 11:56 am 
Expert
Expert

Joined: Sat Jan 17, 2004 2:57 pm
Posts: 329
Location: In the basement in my underwear
I'll address 1 and 2 which should probably correct 3.

The add method checks against hash not equals on add, remove, etc.

If you take a look at the source for HashSet you should see that it uses an underlying HashMap in order to track the elements. This is why you get grief if your hashcode is dynamic and changes.

For example I add an object that hashes to a value of 5. It get put into the map with a key of 5. If my hashcode changes the map never gets updated to reflect this. So, if your key is now 2 and you call add or remove it won't find it in the Set (keys don't match the underlying map) and you will either get a duplicate or the object won't be removed.

Which leads to 2. The hashcode methods aren't actually being called because the set is calling hashCode as himawan states. Change them to hashCode and I should think your problem should go away. Bear in mind if name changes after your objects are placed in the set you can run into issues as outlined in my response to 1.

_________________
Some people are like Slinkies - not really good for anything, but you still can't help but smile when you see one tumble down the stairs.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 30, 2007 9:15 am 
Beginner
Beginner

Joined: Sat Jul 29, 2006 12:29 am
Posts: 27
himawan wrote:
Can you share the equals() and hashCode() method for State?

On your Country and UnidadeFederative class, the the hashcode() function uses lowercase c. Those really should be uppercase. Maybe your state class has the same problem?


Hi himawan.

Your tip solved my problem. By the way, UnidadeFederativa was State. I've forgotten to translate this peace of code.

VampBoy,

Thanks for your explanation.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 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.