symfony icon indicating copy to clipboard operation
symfony copied to clipboard

[DoctrineBridge] weird error with mongodb services

Open chedri opened this issue 3 years ago • 8 comments

Symfony version(s) affected

6.0.7

Description

We are upgrading our software to PHP8 and Symfony 6.

We are having issues with a service that holds current project settings. This is mainly a simple helper for us that just checks which host is being used and fetches information from mongo database. This service is also used in other doctrine listeners (postLoad). Mainly, when we are dealing with user documents. However, the postLoad service is somehow not being properly registered inside of the vendor/symfony/doctrine-bridge/ContainerAwareEventManager.php. When we had a look at the internals of the EventManager, we found out that the event is on the $listeners list, but the according entry in the $methods is missing. During further investigation, we found out that the foreach loop inside of the initializeListeners method is just breaking on the $this->listeners[$eventName][$hash] = $listener = $this->container->get($listener); line (also, other services that we have in the application are not even on the $listeners list; just as if this line of code acted like a break; on the loop). We cannot debug it any further that up to the Container.php class (it seems that the load method should be executed, but it just isn't).

How to reproduce

Still working on that

Possible Solution

No response

Additional Context

ErrorException:
Warning: Undefined array key "postLoad"

  at vendor/symfony/doctrine-bridge/ContainerAwareEventManager.php:73
  at Symfony\Bridge\Doctrine\ContainerAwareEventManager->dispatchEvent('postLoad', object(LifecycleEventArgs))
     (vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php:515)
  at Doctrine\ODM\MongoDB\Hydrator\HydratorFactory->hydrate(object(WhiteLabelSettings), array('id' => '6266c295ad911e7e370300b2', 'owner' => object(Client), 'isDeleted' => false, 'isActive' => true), array(false, false))
     (vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/UnitOfWork.php:2868)
  at Doctrine\ODM\MongoDB\UnitOfWork->getOrCreateDocument('ClientBundle\\Document\\WhiteLabelSettings', array('_id' => object(ObjectId), 'owner' => 'testcompanyuser', 'isDeleted' => false, 'isActive' => true), array(false, false))
     (vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Iterator/HydratingIterator.php:122)
  at Doctrine\ODM\MongoDB\Iterator\HydratingIterator->hydrate(array('_id' => object(ObjectId), 'owner' => 'testcompanyuser', 'isDeleted' => false, 'isActive' => true))
     (vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Iterator/HydratingIterator.php:67)
  at Doctrine\ODM\MongoDB\Iterator\HydratingIterator->current()
     (vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Iterator/CachingIterator.php:169)
  at Doctrine\ODM\MongoDB\Iterator\CachingIterator->wrapTraversable(object(HydratingIterator))
  at Generator->key()
     (vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Iterator/CachingIterator.php:153)
  at Doctrine\ODM\MongoDB\Iterator\CachingIterator->storeCurrentItem()
     (vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Iterator/CachingIterator.php:55)
  at Doctrine\ODM\MongoDB\Iterator\CachingIterator->__construct(object(HydratingIterator))
     (vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Query/Query.php:375)
  at Doctrine\ODM\MongoDB\Query\Query->makeIterator(object(HydratingIterator))
     (vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Query/Query.php:437)
  at Doctrine\ODM\MongoDB\Query\Query->runQuery()
     (vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Query/Query.php:189)
  at Doctrine\ODM\MongoDB\Query\Query->execute()
     (vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Query/Query.php:259)
  at Doctrine\ODM\MongoDB\Query\Query->getIterator()
     (vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Query/Query.php:288)
  at Doctrine\ODM\MongoDB\Query\Query->getSingleResult()
     (bundles/ClientBundle/Model/WhiteLabelWatcher.php:21)
  at ClientBundle\Model\WhiteLabelWatcher->__construct(object(ManagerRegistry), object(RequestStack))
     (var/cache/dev/ContainerZk4ENA6/getWhiteLabelWatcherService.php:22)
  at ContainerZk4ENA6\getWhiteLabelWatcherService::do(object(App_KernelDevDebugContainer), true)
     (var/cache/dev/ContainerZk4ENA6/App_KernelDevDebugContainer.php:434)
  at ContainerZk4ENA6\App_KernelDevDebugContainer->load('getWhiteLabelWatcherService.php')
     (var/cache/dev/ContainerZk4ENA6/getListenerOneService.php:22)
  at ContainerZk4ENA6\getListenerOneService::do(object(App_KernelDevDebugContainer), true)
     (var/cache/dev/ContainerZk4ENA6/App_KernelDevDebugContainer.php:434)
  at ContainerZk4ENA6\App_KernelDevDebugContainer->load('getListenerOneService.php')
     (vendor/symfony/dependency-injection/Container.php:383)
  at Symfony\Component\DependencyInjection\Container->getService('services', 'ClientBundle\\Listener\\ListenerOne', 'getListenerOneService', true)
     (vendor/symfony/dependency-injection/Argument/ServiceLocator.php:48)
  at Symfony\Component\DependencyInjection\Argument\ServiceLocator->get('ClientBundle\\Listener\\ListenerOne')
     (vendor/symfony/doctrine-bridge/ContainerAwareEventManager.php:198)
  at Symfony\Bridge\Doctrine\ContainerAwareEventManager->initializeListeners('postLoad')
     (vendor/symfony/doctrine-bridge/ContainerAwareEventManager.php:62)
  at Symfony\Bridge\Doctrine\ContainerAwareEventManager->dispatchEvent('postLoad', object(LifecycleEventArgs))
     (vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php:515)
  at Doctrine\ODM\MongoDB\Hydrator\HydratorFactory->hydrate(object(Client), array('username' => 'testcompanyuser', 'type' => 'customer', 'password' => '', 'roles' => array('ROLE_USER', 'ROLE_COMPANY'), 'isDeleted' => false, 'isActive' => true), array(false, false))
     (vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/UnitOfWork.php:2868)
  at Doctrine\ODM\MongoDB\UnitOfWork->getOrCreateDocument('ClientBundle\\Document\\Client', array('_id' => 'testcompanyuser', 'isActive' => true, 'isDeleted' => false, 'password' => '', 'roles' => array('ROLE_USER', 'ROLE_COMPANY'), 'type' => 'customer'), array(false, false))
     (vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Iterator/HydratingIterator.php:122)
  at Doctrine\ODM\MongoDB\Iterator\HydratingIterator->hydrate(array('_id' => 'testcompanyuser', 'isActive' => true, 'isDeleted' => false, 'password' => '', 'roles' => array('ROLE_USER', 'ROLE_COMPANY'), 'type' => 'customer'))
     (vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Iterator/HydratingIterator.php:67)
  at Doctrine\ODM\MongoDB\Iterator\HydratingIterator->current()
     (vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Iterator/CachingIterator.php:169)
  at Doctrine\ODM\MongoDB\Iterator\CachingIterator->wrapTraversable(object(HydratingIterator))
  at Generator->key()
     (vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Iterator/CachingIterator.php:153)
  at Doctrine\ODM\MongoDB\Iterator\CachingIterator->storeCurrentItem()
     (vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Iterator/CachingIterator.php:55)
  at Doctrine\ODM\MongoDB\Iterator\CachingIterator->__construct(object(HydratingIterator))
     (vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Query/Query.php:375)
  at Doctrine\ODM\MongoDB\Query\Query->makeIterator(object(HydratingIterator))
     (vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Query/Query.php:437)
  at Doctrine\ODM\MongoDB\Query\Query->runQuery()
     (vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Query/Query.php:189)
  at Doctrine\ODM\MongoDB\Query\Query->execute()
     (bundles/ClientBundle/Controller/ClientController.php:29)
  at ClientBundle\Controller\ClientController->getClientsAction(object(Request), object(ManagerRegistry))
     (vendor/symfony/http-kernel/HttpKernel.php:152)
  at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
     (vendor/symfony/http-kernel/HttpKernel.php:74)
  at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
     (vendor/symfony/http-kernel/Kernel.php:202)
  at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
     (vendor/symfony/runtime/Runner/Symfony/HttpKernelRunner.php:35)
  at Symfony\Component\Runtime\Runner\Symfony\HttpKernelRunner->run()
     (vendor/autoload_runtime.php:29)
  at require_once('/var/www/html/chedri/vendor/autoload_runtime.php')
     (web/index.php:5)  

chedri avatar Apr 25 '22 16:04 chedri

Our composer file:

{
  "name": "chedri/symfony_bug_46168",
  "type": "project",
  "description": "",
  "version": "0.0.1",
  "license": "proprietary",
  "minimum-stability": "stable",
  "prefer-stable": true,
  "require": {
    "php": ">=8.0.0",
    "ext-ctype": "*",
    "ext-iconv": "*",
    "ausi/slug-generator": "^1.1",
    "aws/aws-sdk-php-symfony": "^2.3",
    "digitick/sepa-xml": "^2.1",
    "doctrine/annotations": "^1.13",
    "doctrine/common": "^3.3",
    "doctrine/mongodb-odm-bundle": "^4.4",
    "eightpoints/guzzle-bundle": "^8.3",
    "friendsofsymfony/rest-bundle": "^3.3",
    "imagine/imagine": "^1.3",
    "jms/serializer-bundle": "^4.0",
    "knplabs/knp-snappy-bundle": "^1.9",
    "lexik/jwt-authentication-bundle": "^2.15",
    "nelmio/api-doc-bundle": "^4.8",
    "odolbeau/phone-number-bundle": "^3.6",
    "php-amqplib/rabbitmq-bundle": "^2.11",
    "presta/sitemap-bundle": "^3.3",
    "sensio/framework-extra-bundle": "^6.2",
    "symfony/console": "6.0.*",
    "symfony/dotenv": "6.0.*",
    "symfony/expression-language": "6.0.*",
    "symfony/flex": "^2",
    "symfony/framework-bundle": "6.0.*",
    "symfony/intl": "6.0.*",
    "symfony/mailer": "6.0.*",
    "symfony/runtime": "6.0.*",
    "symfony/security-bundle": "6.0.*",
    "symfony/translation": "6.0.*",
    "symfony/validator": "6.0.*",
    "symfony/webpack-encore-bundle": "^1.14",
    "symfony/yaml": "6.0.*",
    "twig/cssinliner-extra": "^3.3",
    "twig/extra-bundle": "^3.3",
    "twig/intl-extra": "^3.3",
    "twig/twig": "^3.3",
    "wamania/php-stemmer": "^3.0",
    "zbateson/mail-mime-parser": "^2.2"
  },
  "require-dev": {
    "doctrine/doctrine-fixtures-bundle": "^3.4",
    "symfony/stopwatch": "6.0.*",
    "symfony/web-profiler-bundle": "6.0.*"
  },
  "config": {
      "allow-plugins": {
          "composer/package-versions-deprecated": true,
          "symfony/flex": true,
          "symfony/runtime": true
      },
      "optimize-autoloader": true,
      "preferred-install": {
          "*": "dist"
      },
      "sort-packages": true
  },
  "autoload": {
      "psr-4": {
          "App\\": "src/",
          "": "bundles/"
      }
  },
  "autoload-dev": {
      "psr-4": {
          "App\\Tests\\": "tests/"
      }
  },
  "replace": {
      "symfony/polyfill-ctype": "*",
      "symfony/polyfill-iconv": "*",
      "symfony/polyfill-php72": "*",
      "symfony/polyfill-php73": "*",
      "symfony/polyfill-php74": "*",
      "symfony/polyfill-php80": "*"
  },
  "scripts": {
      "auto-scripts": {
        "cache:clear": "symfony-cmd",
        "assets:install %PUBLIC_DIR%": "symfony-cmd"
      },
      "post-install-cmd": [
          "@auto-scripts"
      ],
      "post-update-cmd": [
          "@auto-scripts"
      ]
  },
  "conflict": {
      "symfony/symfony": "*"
  },
  "extra": {
      "symfony": {
          "allow-contrib": false,
          "require": "6.0.*"
      },
      "public-dir": "web"
  }
}

Our services.yml file:

# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.

# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
imports:
    - { resource: parameters.php }
    - { resource: "@ClientBundle/Resources/config/services.yml" }

services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.

    doctrine:
        alias: doctrine_mongodb

    app.user_provider:
        class: ClientBundle\Model\ClientProvider
        arguments: ["@doctrine_mongodb"]

    ClientBundle\Controller\:
        resource: '../bundles/ClientBundle/Controller/'
        tags: ['controller.service_arguments']

    ClientBundle\DataFixtures\ClientFixtures:
        tags: [doctrine.fixture.odm.mongodb]
    ClientBundle\DataFixtures\WhiteLabelSettingsFixtures:
        tags: [doctrine.fixture.odm.mongodb]

    Redis:
        class: Redis
        calls:
            - connect:
                - '%env(REDIS_HOST)%'
                - '%env(int:REDIS_PORT)%'
            - auth:
                - '%env(REDIS_PASSWORD)%'

    Symfony\Component\HttpFoundation\Session\Storage\Handler\RedisSessionHandler:
        arguments:
            - '@Redis'

Our routes.yml file:

client:
    resource: "@ClientBundle/Resources/config/routing.yml"
    prefix: api

The controller:

<?php

namespace ClientBundle\Controller;

use ClientBundle\Model\ClientCollection;

use FOS\RestBundle\Controller\Annotations;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use FOS\RestBundle\View\View;

use Symfony\Component\HttpFoundation\Request;

class ClientController extends AbstractController
{
    /**
     * List all clients.
     * @Annotations\Get("/clients.{_format}")
     *
     * @Annotations\View()
     *
     * @return array
     */
    public function getClientsAction(
        Request $request,
        \Doctrine\Bundle\MongoDBBundle\ManagerRegistry $mongoDb
    )
    {
        $dm = $mongoDb->getManager();
        $list = $dm->createQueryBuilder('ClientBundle:Client')->getQuery()->execute()->toArray(false);
        $count = $dm->createQueryBuilder('ClientBundle:Client')->count()->getQuery()->execute();

        return new ClientCollection($list, $count);
    }
}

And the most important, the services I mentioned in the first post:

services.yaml file:

services:
    _defaults: { public: true, autowire: true }

    ClientBundle\Listener\ListenerOne:
        tags:
            -  { name: doctrine_mongodb.odm.event_listener, event: postLoad }

    ClientBundle\Model\WhiteLabelWatcher:

ListenerOne.php

<?php

namespace ClientBundle\Listener;

use Doctrine\ODM\MongoDB\Event\LifecycleEventArgs;
use Doctrine\ODM\MongoDB\Events;

use ClientBundle\Document\Client;

/**
 *
 */
class ListenerOne
{
    protected $whiteLabelWatcher;

    public function __construct(
        \ClientBundle\Model\WhiteLabelWatcher $whiteLabelWatcher
    ) {
        $this->whiteLabelWatcher = $whiteLabelWatcher;
    }

    public function getSubscribedEvents()
    {
        return [
            Events::postLoad
        ];
    }

    public function postLoad(LifecycleEventArgs $eventArgs)
    {
        if (
            $eventArgs->getDocument() instanceof Client
        ) {
            $eventArgs->getDocument()->getIsActive();
        }
    }
}

and the WhiteLabelWatcher.php:

<?php

namespace ClientBundle\Model;

use Doctrine\ODM\MongoDB\Event\LifecycleEventArgs;
use Doctrine\ODM\MongoDB\Events;

use ClientBundle\Document\Client;

/**
 *
 */
class WhiteLabelWatcher
{
    public function __construct(
        \Doctrine\Bundle\MongoDBBundle\ManagerRegistry $mongoDb,
        \Symfony\Component\HttpFoundation\RequestStack $requestStack,
    )
    {
        $settings = $mongoDb->getManager()->createQueryBuilder('ClientBundle:WhiteLabelSettings')
            ->getQuery()->getSingleResult()
            ;
        $settings->getIsActive();

        if ($requestStack->getCurrentRequest() !== null) {
            $requestStack->getCurrentRequest()->getHost();
        }
    }
}

I'm not sure what could be the problem with the loop just breaking without any trace of an error or exception. Worth to notice is that the WhiteLabelSettings document has a reference to the Client document too (@MongoDb\ReferenceOne).

I will try to create a symfony bug project and deliver it as soon as possible, but maybe someone had an issue like that already?

chedri avatar Apr 25 '22 17:04 chedri

What is the output of composer show?

xabbuh avatar May 05 '22 10:05 xabbuh

Sorry it took so long. Here the composer show result:

doctrine/annotations               1.13.2  Docblock Annotations Parser
doctrine/cache                     2.1.1   PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.
doctrine/collections               1.6.8   PHP Doctrine Collections library that adds additional functionality on top of PHP arrays.
doctrine/deprecations              v1.0.0  A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.
doctrine/event-manager             1.1.1   The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.
doctrine/instantiator              1.4.1   A small, lightweight utility to instantiate objects in PHP without invoking their constructors
doctrine/lexer                     1.2.3   PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.
doctrine/mongodb-odm               2.4.0   PHP Doctrine MongoDB Object Document Mapper (ODM) provides transparent persistence for PHP objects to MongoDB.
doctrine/mongodb-odm-bundle        4.4.2   Symfony Doctrine MongoDB Bundle
doctrine/persistence               2.5.3   The Doctrine Persistence project is a set of shared interfaces and functionality that the different Doctrine object mappers share.
friendsofphp/proxy-manager-lts     v1.0.12 Adding support for a wider range of PHP versions to ocramius/proxy-manager
jean85/pretty-package-versions     2.0.5   A library to get pretty versions strings of installed dependencies
laminas/laminas-code               4.5.1   Extensions to the PHP Reflection API, static code scanning, and code generation
mongodb/mongodb                    1.12.0  MongoDB driver library
psr/cache                          3.0.0   Common interface for caching libraries
psr/container                      2.0.2   Common Container Interface (PHP FIG PSR-11)
psr/event-dispatcher               1.0.0   Standard interfaces for event handling.
psr/log                            3.0.0   Common interface for logging libraries
symfony/cache                      v6.0.6  Provides an extended PSR-6, PSR-16 (and tags) implementation
symfony/cache-contracts            v3.0.1  Generic abstractions related to caching
symfony/config                     v6.0.7  Helps you find, load, combine, autofill and validate configuration values of any kind
symfony/console                    v6.0.7  Eases the creation of beautiful and testable command line interfaces
symfony/dependency-injection       v6.0.7  Allows you to standardize and centralize the way objects are constructed in your application
symfony/deprecation-contracts      v3.0.1  A generic function and convention to trigger deprecation notices
symfony/doctrine-bridge            v6.0.8  Provides integration for Doctrine with various Symfony components
symfony/dotenv                     v6.0.5  Registers environment variables from a .env file
symfony/error-handler              v6.0.7  Provides tools to manage errors and ease debugging PHP code
symfony/event-dispatcher           v6.0.3  Provides tools that allow your application components to communicate with each other by dispatching events and listening to them
symfony/event-dispatcher-contracts v3.0.1  Generic abstractions related to dispatching event
symfony/filesystem                 v6.0.7  Provides basic utilities for the filesystem
symfony/finder                     v6.0.3  Finds files and directories via an intuitive fluent interface
symfony/flex                       v2.1.7  Composer plugin for Symfony
symfony/framework-bundle           v6.0.7  Provides a tight integration between Symfony components and the Symfony full-stack framework
symfony/http-foundation            v6.0.7  Defines an object-oriented layer for the HTTP specification
symfony/http-kernel                v6.0.7  Provides a structured process for converting a Request into a Response
symfony/options-resolver           v6.0.3  Provides an improved replacement for the array_replace PHP function
symfony/password-hasher            v6.0.8  Provides password hashing utilities
symfony/polyfill-intl-grapheme     v1.25.0 Symfony polyfill for intl's grapheme_* functions
symfony/polyfill-intl-normalizer   v1.25.0 Symfony polyfill for intl's Normalizer class and related functions
symfony/polyfill-mbstring          v1.25.0 Symfony polyfill for the Mbstring extension
symfony/polyfill-php81             v1.25.0 Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions
symfony/property-access            v6.0.8  Provides functions to read and write from/to an object or array using a simple string notation
symfony/property-info              v6.0.7  Extracts information about PHP class' properties using metadata of popular sources
symfony/routing                    v6.0.5  Maps an HTTP request to a set of configuration variables
symfony/runtime                    v6.0.7  Enables decoupling PHP applications from global state
symfony/security-bundle            v6.0.8  Provides a tight integration of the Security component into the Symfony full-stack framework
symfony/security-core              v6.0.8  Symfony Security Component - Core Library
symfony/security-csrf              v6.0.3  Symfony Security Component - CSRF Library
symfony/security-http              v6.0.8  Symfony Security Component - HTTP Integration
symfony/service-contracts          v3.0.1  Generic abstractions related to writing services
symfony/string                     v6.0.3  Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way
symfony/translation-contracts      v3.0.1  Generic abstractions related to translation
symfony/validator                  v6.0.8  Provides tools to validate values
symfony/var-dumper                 v6.0.6  Provides mechanisms for walking through any arbitrary PHP variable
symfony/var-exporter               v6.0.7  Allows exporting any serializable PHP data structure to plain PHP code
symfony/yaml                       v6.0.3  Loads and dumps YAML files

chedri avatar May 09 '22 17:05 chedri

I also created a small project to reproduce this problem: https://github.com/chedri/symfony_issue_46168 The only problem I have is I cannot run it without a mongo database. So, a mongo database needs to be created. Then, you also need two documents: the Client and the WhiteLabelSettings (WhiteLabelSettings must have a reference to the Client). Should I provide some JSON objects to import to mongo? I can also add data fixtures if you want.

chedri avatar May 10 '22 07:05 chedri

@xabbuh Could you please have a look? We still could not solve it ourselves. Thank you

chedri avatar Jun 01 '22 09:06 chedri

I didn't have the time yet to set up Mongodb to actually be able to try out your example. Maybe someone else reading this ticket has such a setup and can have a deeper look. Otherwise can you try to debug the event manager's state to identify flaw?

xabbuh avatar Jun 09 '22 06:06 xabbuh

Hey, thanks for your report! There has not been a lot of activity here for a while. Is this bug still relevant? Have you managed to find a workaround?

carsonbot avatar Dec 10 '22 13:12 carsonbot

Just a quick reminder to make a comment on this. If I don't hear anything I'll close this.

carsonbot avatar Dec 30 '22 13:12 carsonbot

Symfony 6 and PHP 8 still have issues with Doctrine Bridge and postLoad method

slavko-chedri avatar Jan 02 '23 07:01 slavko-chedri

I reproduced this bug, thank you very much for the reproducer. I took some hours to dig in this problem.

The error occurs is only with event listeners, but there is an hidden issue if ListenerOne is an event subscriber.

The problem comes from the db query in the constructor of the service WhiteLabelWatcher, which is a dependency of the event listener. I think this is not a good practice to interact with external services in the constructor of services and should postpone the query to the moment you need access to the data.

A solution for your project is to make the service lazy (doc).

For more details, the execution stack is:

  • The controller makes a query and find a document.
  • The postLoad event is called
  • Since the listeners for this event are not initialized, the method ContainerAwareEventManager::initializeListeners is called for the postLoad event. It starts by flagging the listener of this event as initialized.
  • When ListenerOne service is initialized, it loads WhiteLabelWatcher that makes a query and find a document.
  • Again, the postLoad event is called but the listener are not initialized. $initialized['postLoad'] = true.
  • The listeners are called, but that fails.

A see 2 options to improve the DX:

  1. Throw a descriptive exception when the method is not defined. Explaining the loop issue and suggest to use an event subscriber or a lazy service. Done in #48955
  2. ~Or make all event listeners lazy by default~ (does not fix event subscribers)

GromNaN avatar Jan 12 '23 00:01 GromNaN

Hey, thanks for your report! There has not been a lot of activity here for a while. Is this bug still relevant? Have you managed to find a workaround?

carsonbot avatar Jul 13 '23 13:07 carsonbot

Could I get an answer? If I do not hear anything I will assume this issue is resolved or abandoned. Please get back to me <3

carsonbot avatar Jul 30 '23 12:07 carsonbot

Hey,

I didn't hear anything so I'm going to close it. Feel free to comment if this is still relevant, I can always reopen!

carsonbot avatar Aug 13 '23 12:08 carsonbot