Bug #84779
closedQueryInterface->execute() should do a rewind() before returning to avoid mismatch between content and count
0%
Description
It is possible to create situations in which the QueryResult
content of a repository mismatches the QueryResult->count()
. This seems to happen in statement()
mode (writing raw SQL) and can also occur in language overlays (when not all or even none of the objects are translated). In these situations it is possible that, after the initial (raw or L=0
) query is done, some objects are removed from the result (L>0
does not exist or enable fields are applied to the result from the raw statement), but the internal count is not updated then.
This is especially problematic for empty QueryResults that are presented as non-empty. In consequence <f:if condition="{queryResult}">
can return true for empty results or $queryResult->count()
can mismatch. Doing f:debug
(or a regular Extbase var_dump
) on such a QueryResult shows the object as non-empty, but as soon as one tries to open the list of items it's empty.
Using the QueryResult
only in a foreach loop does not have this problem, as the rewind is done implicitly then, though the \Iterable
interface, but all non-\Iterable
actions acting on the count()
can behave weird.
In our projects we adopted to always doing ->rewind()
before returning from the Repository find
method. But ideally this should happen already in the execute()
method automatically as the very last action before returning to ensure consitency between content and counter.
This happens in TYPO 7 and 8.
Updated by S P over 6 years ago
- Subject changed from QueryResult->execute() should do a rewind() before returning to QueryResult->execute() should do a rewind() before returning to avoid mismatch between content and count
Updated by S P over 6 years ago
- Subject changed from QueryResult->execute() should do a rewind() before returning to avoid mismatch between content and count to QueryInterface->execute() should do a rewind() before returning to avoid mismatch between content and count
Updated by Alexander Schnitzler over 4 years ago
- Assignee set to Stefan Froemken
Updated by Stefan Froemken over 4 years ago
Hello Stefan,
sorry, I can understand this problem and I know this problem a long time. If your statement contains a JOIN, your aggregate root may appear multiple times, but with different related records. In that case extbase fetches the first aggregate root record and stores the mapped DomainModel in Session Object of Extbase. Processing the next record, which contains the same record as before, will not access the db again. Instead it will get DomainModel from Session Object. So you never have the possibility to create multiple aggregate roots with same UID and different related records each.
We can not call rewind() automatically by extbase as this will start mapping DomainModels directly. We have DBs queries with over 150.000 records. This will fill RAM drastically and counting the objects may feel like years.
Solving this issue performant incl. repairing all side-effects (Session-object) would nearly break everything.
You know how many records you have and how many you want to select. So IMO it would be better to close this ticket and call ->rewind() yourself.
Stefan
Updated by Alexander Schnitzler over 4 years ago
- Status changed from New to Rejected