eclipselink
eclipselink copied to clipboard
BatchFetch IN corrupts cache by overwriting BatchFetchPolicy dataResults
EclipseLink version 4.0.2
When loading more referenced entities by @BatchFetch(value = BatchFetchType.IN)
than the BatchFetch size (seems to be fixed 500, the annotation value is not used), multiple queries are issued to retrieve all results. But the IN (...)
arguments for the last issued query are stored in the cache for every retrieved entity as "source" query arguments, which means that all entities which were not fetched with the last query have corrupted @OneToMany
references (when loading them, an empty collection is returned because the query uses the wrong IDs).
The cause is BatchFetchPolicy.setDataResults which overwrites the previous rows. I implemented a dirty workaround by adding the results in executeObjectLevelReadQuery() instead of overwriting them, but this could cause bad performance because the number of rows can grow larger than the BatchFetch size, resulting in multiple queries when querying again.
This is relatively complicated to describe but very easy to reproduce. There is a simple test case attached with
- two entity types (
Parent
andChild
) - bidirectional
@OneToMany
/@ManyToOne
with@BatchFetch(value = BatchFetchType.IN)
- persist 501 parents with 1 child each
- query all parents -> OK
- query all children
- observe that all parents apart from the 501st one seem to have no children anymore. FINE logging to see the wrong query.