Natural Id 2nd level Cache not working when Identity is database generated

Description

When an entity has a database generated identity and an immutable natural identity, identity values are supposed to be cached in second level cache when configured.
There seems to be a bug in public void org.hibernate.action.internal.AbstractEntityInsertAction.handleNaturalIdPostSaveNotifications(Serializable generatedId) method.
It receives a valid generated Id value, but disregards it when calling PersistenceContext$NaturalIdHelper.manageSharedNaturalIdCrossReference(...). It passes getId() method result which evaluates to null.
This causes null id value to be cached against the natural id value.
Then, every time the entity is looked up by the natural id value, cache returns null. Identity is looked up in the database, but not cached, because cache access strategy (ReadWriteEhcacheNaturalIdRegionAccessStrategy) never updates cache entries (they supposed to immutable).
In our system these lookups increase the database load dramatically.

Environment

Hibernate 4.3, 5.0 and 5.1
MS SQL Server and HSQL DB

Activity

Show:
DamienD
September 13, 2016, 5:09 AM

We have been investigating some strange statistics with our natural id caches, specifically, millions of misses and puts but 0 hits.

We have tracked the issue down to the same code that Andrey has identified:

It seems like changing getId() to generatedId would resolve the issue. We will fork the project and test the fix.

Vlad Mihalcea
September 20, 2016, 12:23 PM

, you might want to backport this issue to 5.1 and 5.0.

Gail Badner
September 24, 2016, 1:27 AM

Fixed in 5.1 and 5.0 branches as well.

Assignee

Vlad Mihalcea

Reporter

Andrey Zavodnik

Fix versions

backPortable

None

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

Components

Affects versions

Priority

Major
Configure