If you suddenly experience problems callling set.remove()
and set.contains()
on your Java Set instances, you might be using Hibernate, which replaces your Set instance with its own version (PersistentSet), which uses a HashSet internally to store your data.
For example, the problem I faced was the following:
Person.java
public class Person(){ String _name; public Person(String name){ _name = name; } @Override public String toString(){ return _name; } @Override public int hashCode(){ if (_name != null) return _name.hashCode(); return -1; } }
MyTestApplication.java
public class MyTestApplication{ public static void main(String[] args){ Person steve = new Person("Steve"); Set persons = new Set(); persons.add(steve); System.out.println(persons); boolean contains = persons.contains(steve); System.out.println(String.valueOf(contains)); persons.remove(steve); System.out.println(persons); for (Person person : persons){ System.out.println("Contains: " + person.toString()); } } }
The code above prints the following to the console:
[Steve]
false
[Steve]
Contains: Steve
This definitely was not expected.
The reason: If you call set.remove(obj)
or set.contains(obj)
, the internal HashSet will automatically call obj.hashCode()
and use the returned value to search for obj.
Normally, this works without any issues, but there is one case where it doesn’t and that’s when:
- You use Hibernate
- You load the Set data eagerly
- You override the
obj.hashCode()
method
The reason for this is a bug in Hibernate.
For me, a solution was to not override the obj.hashCode()
method.
Since this is not a solution for all cases, I recommend to follow the link above and read through the comments. There are quite some workarounds described there. I’m sure one of them will work for you.
Good luck, soldier.
(God, Hibernate! I officially hate you now. It took me a whole day to find the reason for this issue).
Thank you very much !
I started to think I was “as dumb as a chair” as we say in french. But alright, Hibernate tricked me once again. Thank you once again, very useful post.
I just hammered into it as well. Thank you for confirming I am not a total looser.
I’m glad that my post was helpful to you! :-)
Couldn’t you take your time to write the solution? The link is down now rendering this usefull post useless
Found it. It was migrated to newer JIRA.
https://hibernate.atlassian.net/browse/HHH-3799
Hope it helps!
Awesome, thanks for sharing Bartosz! I updated the link in the post.
Wow, I just fell into this trap :(
Thank you for posting this!
You’re very welcome :)
Glad I could help!
Plzz where is the link i have the same prob and i still can’t fix it
Try the suggestions here: https://hibernate.atlassian.net/plugins/servlet/mobile?originPath=%2Fbrowse%2FHHH-3799#issue/HHH-3799
This blog post is very old and I don’t really remember what the solution was 😅