Bug #65022
closedProblem with propertyMapper when using custom queries (extbase)
0%
Description
I just wrote an extension and tried to select some addtional data:
// Repository: $sql = 'select *, min(columnname) as fictionalcolumn'; // and so on... return $query->statement($sql)->execute();
And I added the fictionalcolumn to the model (declared as string with getter and setter).
But when I tried to use the fictionalcolumn in my template, it was empty. I investigated the problem with the help of Dennis Römmich (thanks!) and he found the cause at typo3/sysext/extbase/Classes/Persistence/Generic/Mapper/DataMapper.php - function mapSingleRow().
/** * Maps a single row on an object of the given class * * @param string $className The name of the target class * @param array $row A single array with field_name => value pairs * @return object An object of the given class */ protected function mapSingleRow($className, array $row) { if ($this->identityMap->hasIdentifier($row['uid'], $className)) { $object = $this->identityMap->getObjectByIdentifier($row['uid'], $className); } else { $object = $this->createEmptyObject($className); $this->identityMap->registerObject($object, $row['uid']); $this->thawProperties($object, $row); $object->_memorizeCleanState(); $this->persistenceSession->registerReconstitutedEntity($object); } return $object; }
Because there is an uid in the DB result, the data from $row is not used anymore. Thus the value from fictionalcolumn gets lost. Maybe a call to thawProperties() in the if-branch would solve the problem.
Until then, a workaround could be to call $query->getQuerySettings()->setReturnRawQueryResult(TRUE); in the repository before executing the query.
Updated by Stefan Froemken over 1 year ago
- Status changed from New to Closed
Hello,
thank you for reporting that issue, I remember that issue year ago. Yes, the records are identified by just the UID. So, if you're working with aggregate functions like MAX, MIN, AVG of DB you will fall into that problem. Maybe you have seen that extbase Query does not support GROUP BY in general. That's done to prevent such problems.
So, if you really need aggregate functions I prefer using
... protected DataMapper $dataMapper; ... public function injectDataMapper(DataMapper $dataMapper): void { $this->dataMapper = $dataMapper } ... public function getRecords() { $records = $query->execute(true); return $this->dataMapper->map(MyDomainModel::class, $records); } ...
Stefan