[
https://hibernate.onjira.com/browse/HHH-3799?page=com.atlassian.jira.plug...
]
David Tarico commented on HHH-3799:
-----------------------------------
In my scenario, objects have a name, which in the database is a non-nullable field and has
a unique constraint, but it's not the primary key. The PK is an auto-generated
integer. I need to fetch an already persisted set, and add a new item if it doesn't
already exist.
It seems natural to make equals/hashCode use the name for identity, and then use a set to
avoid duplicates.
The problem with your proposed hashCode is that it assumes either all the entities in the
collection are persistend, or all are new and don't have an ID.
Assume we have two objects, FOO and BAR, both which have the same name. FOO is persisted
and in the set, but BAR is new and not yet in the set. If I do set.contains(BAR) it will
return false, and if I do set.add(BAR) it will succesfully add BAR and have both FOO and
BAR in the set, causing a unique constraint violation when persisted.
Using a buisness key such as name is a common practice and is even the example given in
Java Persistence with Hibernate in the section on "Object identity and equality"
where they have a User with this example of hashCode:
public int hashCode() {
return username.hashCode();
}
Our hashCode actually looks like
public int hashCode() {
if (name == null) {
return 0;
}
else {
return name.hashCode();
}
}
It took a couple developers more than a day to figure out why the set was not finding the
elements that were already in it and allowing the addition of duplicates. We had to work
around the problem by using a list instead of a set, and adding our own code to check for
duplicates before adding an item. But in my opinion, that makes PersistentSet broken and
unusable because it violates the contract of how hashCode() is expected to behave.
PersistentSet does not honor hashcode/equals contract when loaded
eagerly
-------------------------------------------------------------------------
Key: HHH-3799
URL:
https://hibernate.onjira.com/browse/HHH-3799
Project: Hibernate ORM
Issue Type: Bug
Components: core
Affects Versions: 3.3.1, 3.5.1
Reporter: Igor Vaynberg
Assignee: Gail Badner
Attachments: test.zip
when persistent set is loaded eagerly in some situations it calls hashcode on its items
before their field values are populated and then uses this incorrect hashcode to store
them in the set. this makes set items inaccessible by any collection items that rely on
hashcode such as contains(), remove(), etc.
attached is a simple maven test project that reproduces the error, unzip and mvn test to
run the test.
--
This message is automatically generated by JIRA.
For more information on JIRA, see:
http://www.atlassian.com/software/jira