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.
Hibernate 4.3, 5.0 and 5.1
MS SQL Server and HSQL DB
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.
, you might want to backport this issue to 5.1 and 5.0.
Fixed in 5.1 and 5.0 branches as well.