Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

setFetchMode does not respect second level association #11599

Open
aalgogiver opened this issue Sep 15, 2024 · 0 comments
Open

setFetchMode does not respect second level association #11599

aalgogiver opened this issue Sep 15, 2024 · 0 comments

Comments

@aalgogiver
Copy link

Bug Report

Q A
BC Break no
Version 3.2.1

Summary

Calling setFetchMode with ClassMetadata::FETCH_EAGER does not respect second level association.

Current behavior

When I add the following testing method to tests/Tests/ORM/Functional/BasicFunctionalTest.php it fails

    public function testManyToOneSecondLevelEagerAssociationWithSetFetchMode(): void
    {
        $user           = new CmsUser();
        $user->username = 'beberlei';
        $user->name     = 'Benjamin E.';
        $user->status   = 'active';

        $article1        = new CmsArticle();
        $article1->topic = 'foo';
        $article1->text  = 'bar';
        $article1->user  = $user;

        $article2        = new CmsArticle();
        $article2->topic = 'bar';
        $article2->text  = 'foo';
        $article2->user  = $user;

        $comment1 = new CmsComment();
        $comment1->article = $article1;
        $comment1->topic = 'foo';
        $comment1->text = 'comment1';

        $comment2 = new CmsComment();
        $comment2->article = $article2;
        $comment2->topic = 'bar';
        $comment2->text = 'comment2';

        $this->_em->persist($article1);
        $this->_em->persist($article2);
        $this->_em->persist($comment1);
        $this->_em->persist($comment2);
        $this->_em->persist($user);
        $this->_em->flush();
        $this->_em->clear();

        $this->getQueryLog()->reset()->enable();
        $dql   = 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u';
        $users = $this->_em->createQuery($dql)
                             ->setFetchMode(CmsUser::class, 'articles', ClassMetadata::FETCH_EAGER)
                             ->setFetchMode(CmsArticle::class, 'comments', ClassMetadata::FETCH_EAGER)
                             ->getResult();

        foreach ($users as $user) {
            foreach ($user->articles as $article) {
                $article->comments->initialize();
            }
        }

        // 1 query for users, 1 for articles, 1 for comments and 1 for addresses (CmsUser::$address relation)
        $this->assertQueryCount(4);
    }

and produces 5 queries instead of expected 4 due to fetching comments separately for each article.

How to reproduce

Use the code snippet above.

Expected behavior

Should work in a similar way to the following passing test when relation's mode is being set explicitly.

    public function testManyToOneSecondLevelEagerAssociationWithClassMetadata(): void
    {
        $user           = new CmsUser();
        $user->username = 'beberlei';
        $user->name     = 'Benjamin E.';
        $user->status   = 'active';

        $article1        = new CmsArticle();
        $article1->topic = 'foo';
        $article1->text  = 'bar';
        $article1->user  = $user;

        $article2        = new CmsArticle();
        $article2->topic = 'bar';
        $article2->text  = 'foo';
        $article2->user  = $user;

        $comment1 = new CmsComment();
        $comment1->article = $article1;
        $comment1->topic = 'foo';
        $comment1->text = 'comment1';

        $comment2 = new CmsComment();
        $comment2->article = $article2;
        $comment2->topic = 'bar';
        $comment2->text = 'comment2';

        $this->_em->persist($article1);
        $this->_em->persist($article2);
        $this->_em->persist($comment1);
        $this->_em->persist($comment2);
        $this->_em->persist($user);
        $this->_em->flush();
        $this->_em->clear();

        $classMetadata = $this->_em->getClassMetadata(CmsArticle::class);

        $fetchMode = $classMetadata->associationMappings['comments']['fetch'];
        $classMetadata->associationMappings['comments']['fetch'] = ClassMetadata::FETCH_EAGER;

        $this->getQueryLog()->reset()->enable();
        $dql   = 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u';
        $users = $this->_em->createQuery($dql)
                             ->setFetchMode(CmsUser::class, 'articles', ClassMetadata::FETCH_EAGER)
                             ->getResult();

        $classMetadata->associationMappings['comments']['fetch'] = $fetchMode;

        foreach ($users as $user) {
            foreach ($user->articles as $article) {
                $article->comments->initialize();
            }
        }

        // 3 separate queries for users, articles, comments and 1 for addresses
        $this->assertQueryCount(4);
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant