PersistentSet does not honor hashcode/equals contract when loaded eagerly

Description

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.

Environment

None

Activity

Show:
Ondrej Bozek
July 14, 2016, 6:53 PM
Edited

This issue still holds for Hibernate 5.1.

rzo1
February 1, 2017, 10:56 PM
Edited

This issue is still present in 5.2.7 and has some major impacts on applications... a lot of developers are spending time in debugging this behaviour unless they find this issue...

Vlad Mihalcea
February 2, 2017, 10:33 PM
Edited

As a workaround, it's much better to stick to LAZY collections. EAGER fetching is bad for performance, can lead to Cartesian Products, and you can't paginate the collection.

Query-based fetching is almost always a better alternative to EAGER fetching.

Vlad Mihalcea
February 2, 2017, 10:55 PM

, do you think it's possible to fix this issue. [I've been seeing many complaining](https://twitter.com/zowalla/status/826838154732765185) about spending many hours trying to debug it and figure out that this is a known problem.

Gail Badner
March 1, 2018, 4:59 PM

I think I have a pretty good idea about how to fix this now.

I've added a branch to my fork to work on this: https://github.com/gbadner/hibernate-core/tree/HHH-3799-master

To start, I've made a very quick-and-dirty change that should fix this issue, but it needs to be refined because it is not going to perform well. For now, it simply clears and re-inserts the elements in every collection that gets initialized within a top-level load operation.

It would help a lot if someone could try out this this fix. If it does not work for you, then please attach a runnable test case that reproduces the failure. Test templates can be found at https://github.com/hibernate/hibernate-test-case-templates.

I would really appreciate feedback before refining the fix.

A "refined" fix would only clear and re-insert the elements if all of the following are true:
1) collection element type is an entity or an embeddable (or sub-embeddable, etc) that contains an entity;
2) collection element type or subclasses override Object#hashCode;
3) an entity element or an entity within an embeddable element has org.hibernate.engine.spi.Status.LOADING at the time that it was added to the collection;
4) the hashCode for the element before inserting the element is different from the hashCode of the element after the top-level load completes.

Assignee

Gail Badner

Reporter

IgorI

Fix versions

Labels

None

backPortable

None

Suitable for new contributors

None

Requires Release Note

Affirmative

Pull Request

None

backportDecision

None

Components

Affects versions

Priority

Major