Bug: Using session.list()
with @EmbeddedId
causes bad cache hits
#89
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Currently, when a session is populating its cache, it does so by extracting they "key" of an entity, and comparing it to the "key" as read from database columns. However, this logic only reads a single column, thus,
@EmbeddedId
keys will falsely match in the cache, resulting in a call tosession.list()
returning the same cached Entity multiple times instead of reading each row.While this can be fixed by modifying the
getKey
method ofmetadata.EntityInfo
, this is not a complete solution, because the cache first callsnormalize
on theVariant
which is used as a key.normalize
is not aware of objects, it has special cases forlong
andint
, and everything else usestoString
, meaning that allObject
instances (unless they implementtoString
) will have the same cache key. This is resolved by modifyingnormalize
to simply return aVariant
containing an object as-is, which relies onopEquals
being implemented.This means that, if an
@EmbeddedId
property refers to an@Embeddable
entity that does NOT implementopEquals
, then it will never be considered a cache-hit. This limitation was added to the documentation and README, so that users wishing for the performance benefit of the cache remember to implementopEquals
.Variant normalize(Variant v)
is used to form session cache keys, it was modified to support object keys used by@EmbeddedId
.EntityInfo.getKey(DataSetReader r, int startColumn)
has been renamed togetKeyFromColumns
to disambiguate it from another overload. Added logic to read multiple columns for an@EmbeddedId
key.