admin管理员组

文章数量:1336311

I am blocked with a lazy loading issue that appeared suddenly with doctrine, maybe after I have cleaned my vendor and cache folders and did run composer install.

In my symfony app, I have 3 Entities related: User, UserProfile and Address.

User entity

#[ORM\Entity(repositoryClass: UserRepository::class)]
#[UniqueEntity(fields: ['email'], message: 'There is already an account identified by this email')]
class User implements UserInterface, PasswordAuthenticatedUserInterface, TwoFactorInterface
{
    #[ORM\Id]
    #[ORM\GeneratedValue(strategy: 'CUSTOM')]
    #[ORM\Column(type: 'uuid', unique: true)]
    #[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
    #[Groups([GRP_USER_READ, SerializationGroups::REST_R, SerializationGroups::LICENCE_R])]
    private $uuid;

    #[Groups([GRP_USER_READ, SerializationGroups::REST_R, SerializationGroups::LICENCE_R])]
    #[ORM\Column(type: 'string', length: 180, unique: true)]
    #[Assert\NotBlank]
    #[Assert\Email]
    private $email;

    #[ORM\OneToOne(cascade: ['persist', 'remove'])]
    #[Groups([SerializationGroups::REST_R, SerializationGroups::LICENCE_R])]
    private ?UserProfile $profile = null;

...

The UserProfile Entity:

#[ORM\Entity(repositoryClass: UserProfileRepository::class)]
class UserProfile extends BaseEntity
{
    #[Groups([SerializationGroups::REST_R, SerializationGroups::LICENCE_R])]
    #[ORM\Column(length: 50)]
    private ?string $firstName = null;

    #[Groups([SerializationGroups::REST_R, SerializationGroups::LICENCE_R])]
    #[ORM\Column(length: 50)]
    private ?string $lastName = null;

    #[ORM\OneToOne(cascade: ['persist', 'remove'])]
    #[Groups(SerializationGroups::REST_R)]
    private ?Address $deliveryAddress = null;

    #[ORM\OneToOne(cascade: ['persist', 'remove'])]
    #[Groups(SerializationGroups::REST_R)]
    private ?Address $billingAddress = null;

...

And the Address Entity:

#[ORM\Entity(repositoryClass: AddressRepository::class)]
class Address extends BaseEntity
{
    #[ORM\Column(type: Types::TEXT, nullable: true)]
    private ?string $text = null;

    #[ORM\Column(length: 80, nullable: true)]
    private ?string $contactEmail = null;

    #[Groups(SerializationGroups::REST_R)]
    #[ORM\ManyToOne(targetEntity: Country::class)]
    private ?Country $country = null;

    #[ORM\Column]
    private ?bool $isMain = null;

    #[ORM\Column]
    private ?bool $isDelivery = null;

    #[ORM\Column]
    private ?bool $isBilling = null;

    #[Groups(SerializationGroups::REST_R)]
    #[ORM\Column(length: 10, nullable: true)]
    private ?string $postCode = null;

...

That said, when I try to get any attribute of the object like this:

$currentUser->getProfile()->getBillingAddress()

It always returns null.

After running a debug session, I see that $currentUser->getProfile() returns an object of type \Proxies_CG_\App\Entity\UserProfile, which is the normal doctrine behavior. And now for each relation I have to fetch it using a repository meaning that the direct queries are still working.

I tried the following:

  • run bin/console cache:clear
  • remove the cache and vendor folders and rerun composer install
  • update doctrine schema but no difference has been detected
  • checked if the database returned the relations correctly using subqueries

What can be done to resynchronize doctrine with the database?

My environment:

  • php 8.2
  • symfony 6.2
  • doctrine/orm 2.20.0
  • mysql 8.0
  • docker

UPDATE (21.11.24)

Based on the following configuration I had

doctrine:
    dbal:
        url: '%env(resolve:DATABASE_URL)%'

        # IMPORTANT: You MUST configure your server version,
        # either here or in the DATABASE_URL env var (see .env file)
        #server_version: '13'
    orm:
        dql:
            string_functions:
                JSON_EXTRACT: Scienta\DoctrineJsonFunctions\Query\AST\Functions\Mysql\JsonExtract
                JSON_SEARCH: Scienta\DoctrineJsonFunctions\Query\AST\Functions\Mysql\JsonSearch
                JSON_CONTAINS: Scienta\DoctrineJsonFunctions\Query\AST\Functions\Mysql\JsonContains
        auto_generate_proxy_classes: false
        enable_lazy_ghost_objects: true
        naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
        auto_mapping: true
        mappings:
            App:
                is_bundle: false
                dir: '%kernel.project_dir%/src/Entity'
                prefix: 'App\Entity'
                alias: App
            gedmo_translatable:
                type: attribute
                prefix: Gedmo\Translatable\Entity
                dir: "%kernel.project_dir%/vendor/gedmo/doctrine-extensions/src/Translatable/Entity"
                alias: GedmoTranslatable # (optional) it will default to the name set for the mapping
                is_bundle: false

I had to set enable_lazy_ghost_objects to false and it's working. According to the symfony doc, this flag "Enables the new implementation of proxies based on lazy ghosts instead of using the legacy implementation". I decided to enable it for performance, it used to work actually. Now I'm wondering what would be the right config to optimize performance a bit according to lefacy implementation.

本文标签: phpDoctrine lazy loading returns all relations with null valueStack Overflow