Hello,
many entities in my application are read-only, so I use the mutable="false" setting in their mapping files. This causes Hibernate to set their status to read-only and omit the snapshot creation (TwoPhaseLoad, lines 172-178).
This read-only status in turn optimizes flushing performance since the PersistenceContext's "hasNonReadOnlyEntities" flag is false when only read-only entities are in a session, causing flushing attempts to abort immediately.
However, when I turn on the second-level-cache for an immutable entity type, the entry status is not restored to read-only when an instance is assembled from the second-level-cache:
DefaultLoadEventListener, method assembleCacheEntry, lines 566+:
Code:
persistenceContext.addEntry(
result,
Status.MANAGED,
values,
null,
id,
version,
LockMode.NONE,
true,
subclassPersister,
false,
entry.areLazyPropertiesUnfetched()
);
The Status is always set to MANAGED which causes the PersistenceContext's hasNonReadOnlyEntities to switch to true, which causes a severe hit in flushing performance when the session is large and contains only read-only entities.
This behaviour could probably be fixed by changing Status.MANAGED in the above code to:
persister.isMutable() ? Status.MANAGED : Status.READ_ONLY
This would be consistent with the the code in TwoPhaseLoad.
Any comments?