Feature #60460


Epic #55070: Workpackages

Epic #55065: WP: Overall System Performance (Backend and Frontend)

Epic #55656: Optimize overall Extbase performance

Story #55168: Optimize Extbase generic persistence

Task #55169: Extbase: fetch child objects in one query

Refactor lazyLoading handling in extbase

Added by Felix Oertel almost 10 years ago. Updated over 6 years ago.

Could have
Target version:
Start date:
Due date:
% Done:


Estimated time:
PHP Version:
Sprint Focus:


For quiet some time now I wanted to refactor the lazyLoading handling in extbase.

It stinks, that the lazyLoadingProxy does not extend the actual class, thus fataling when using correct typehints. This leads to developers allways resolving the lazyLoadingProxy which - let's face it - kind of goes against what lazyLoading was intended to do. ;-)

So we need a lazyProxy, which extends the actual class, eliminating the need to ever resolve a lazyProxy if no property is called.

Related issues 2 (0 open2 closed)

Related to TYPO3 Core - Bug #60913: Cannot edit lazy loaded objectsClosed2014-08-12

Related to TYPO3 Core - Task #59917: User Repositories in internal persistence logicRejectedFelix Oertel2014-06-272014-07-09

Actions #1

Updated by Stefano Kowalke almost 10 years ago

The new implementation introduces a LazyLoadingProxyFactory which generates a LazyProxy object which extends the concrete object. With this way proxy objects will pass type hints.

The implementation in detail:


The class can be found at \TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxyFactory. To retrieve a lazy proxy object call the get() method of the class, which expects three parameters:

  1. The classname or object to create the proxy from
  2. The parent object
  3. The property
  4. The value of the field

$this->lazyProxyFactory->getProxy($propertyMetaData['type'], $parentObject, $propertyName, $fieldValue);

The generated proxy class is cached and you will find it at typo3temp/Cache/Code/extbase_lazyproxyobject_storage/*LazyProxy.php


Lets use the blog_example as … well … as an example:

At some point the DataMapper calls $this->lazyProxyFactory->getProxy(…) with this values:
  1. string $className: ExtbaseTeam\BlogExample\Domain\Model\Administrator
  2. object $parentObject: ExtbaseTeam\BlogExample\Domain\Model\Blog
  3. string $propertyName: administrator
  4. string $fieldValue: 351

Here is the code of the generated AdministratorLazyProxy.php:

namespace ExtbaseTeam\BlogExample\Domain\Model;
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;

 * This class is generated by the LazyProxyFactory of Extbase. Don't change the file by yourself!
class AdministratorLazyProxy extends \ExtbaseTeam\BlogExample\Domain\Model\Administrator implements \TYPO3\CMS\Extbase\Persistence\Generic\LoadingStrategyInterface {
    private $parentObject;
    private $propertyName;
    private $fieldValue;
    private $parentQueryResult;

    public function __construct($parentObject, $propertyName, $fieldValue) {
        $this->parentObject = $parentObject;
        $this->propertyName = $propertyName;
        $this->fieldValue = $fieldValue;

    public function setUsername($username) {
        return parent::setUsername($username);

    public function getUsername() {
        return parent::getUsername();


      * @param QueryResultInterface $queryResult
      * @return void
    public function setParentQueryResult(QueryResultInterface $queryResult) {
        $this->parentQueryResult = $queryResult;

     * Returns the parentObject so we can populate the proxy.
     * @return object
    public function _getParentObject() {
        return $this->parentObject;

     * Returns the fieldValue so we can fetch multiple LazyObjects in one query.
     * @return mixed
    public function _getFieldValue() {
        return $this->fieldValue;

The proxy class overrides all public methods from his parent with his own variant of the methods. This just just add a call to the methods whereby the proxy is able to resolve himself. At the end it will return the requested value from the concrete object.

Actions #2

Updated by Mathias Brodala almost 10 years ago

Can you push a changeset to Gerrit to get this ball rolling again?

Actions #3

Updated by Felix Oertel almost 10 years ago

Hey Mathias,

sorry, the patch was with me for some polish ... an I was on vacation. ;-) But it's ready now and I am gonna push it today.

Actions #4

Updated by Mathias Schreiber over 9 years ago

  • Target version changed from 7.0 to 7.1 (Cleanup)
Actions #6

Updated by Christian Kuhn almost 9 years ago

the pending patch was abandoned.

Actions #7

Updated by Benni Mack almost 9 years ago

  • Target version changed from 7.1 (Cleanup) to 7.4 (Backend)
Actions #8

Updated by Susanne Moog almost 9 years ago

  • Target version changed from 7.4 (Backend) to 7.5
Actions #9

Updated by Benni Mack over 8 years ago

  • Status changed from Accepted to New
  • Target version deleted (7.5)
Actions #10

Updated by Ernesto Baschny almost 8 years ago

Since this was abandoned, I suspect that this "documentation" is obsolete?

Our developers today stumbled over the update + LazyLoading bug and found this wiki page, and it looks as if it is a "documentation" for a feature which was never released.
Could someone that is aware of it please mark the status of that page accordingly?

Other than that, the idea is still valid, as the issue is still there: developers are currently forced to do if(LazyLoadingProxy) then _loadRealInstance() in different places. Even the core does so (see typo3/sysext/fluid/Classes/ViewHelpers/Form/AbstractFormViewHelper.php).

Actions #11

Updated by Ernesto Baschny almost 8 years ago

I just marked the page as outdated. Thanks!

Actions #12

Updated by Benni Mack over 6 years ago

  • Status changed from New to Closed

we won't do that anymore


Also available in: Atom PDF