Skip to content

Fix duplicate data in Eager loads relations #2183

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

Merged
merged 3 commits into from
Sep 4, 2018

Conversation

ilicmsreten
Copy link
Contributor

Q A
Bug fix? yes
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets
License MIT
Doc PR

This PR is related to reported bug in api-platform/api-platform project.

So problem is caused because the same tables is joined multiple times ON same condition but with different aliases.

I find useful article by Marco Pivetta about Doctrine hydration where they said about coding multi-step hydration, that is used in PR.

@@ -232,6 +232,8 @@ private function joinRelations(QueryBuilder $queryBuilder, QueryNameGeneratorInt

$this->joinRelations($queryBuilder, $queryNameGenerator, $mapping['targetEntity'], $forceEager, $fetchPartial, $associationAlias, $options, $normalizationContext, 'leftJoin' === $method, $joinCount, $currentDepth);
}

$queryBuilder->getQuery()->getResult();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mhhh but this will execute the query multiple time right? I don't get the point.

May we have a test illutrating the bug in api-platform/api-platform#799 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@soyuka that will not affect performance. The whole process is described here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume you're talking about the comment saying: // result is discarded (this is just re-hydrating the collections). May you add a comment like this because it's really confusing if you're not familiar with doctrine internals...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@soyuka sure, also I will also add tests to cover this

@soyuka soyuka merged commit b64da31 into api-platform:2.3 Sep 4, 2018
@soyuka
Copy link
Member

soyuka commented Sep 4, 2018

thanks @ilicmsreten !

@ilicmsreten ilicmsreten deleted the fix-duplicate-data branch September 4, 2018 14:32
ilicmsreten added a commit to ilicmsreten/core that referenced this pull request Sep 4, 2018
@raziel057
Copy link

raziel057 commented Sep 17, 2018

Hi, this PR generate an issue when getting data from a table containing lots of data because a query is generated and hydration is done without any LIMIT. This is linked to the fact the PaginationExtension is not yet applied to the query builder.

As you can see in https://github.com/api-platform/core/blob/master/src/Bridge/Doctrine/Orm/CollectionDataProvider.php, when calling applyToCollection when iterating first on EagerLoadingExtension, a query is done without the LIMIT.

For me getResult should never be called directly in applyToCollection of any extension.

@raziel057
Copy link

@soyuka @dunglas Could you please revert this PR? It produce a lot of errors on existing APIs.

@raziel057
Copy link

Or if you wants to keep the multi step hydration it should be done after all other extensions...

@soyuka
Copy link
Member

soyuka commented Sep 19, 2018

Or if you wants to keep the multi step hydration it should be done after all other extensions...

We will definitely look into this asap because performances could be improved. Sorry about the mistake, we're in the process of tagging 2.3.3 which will revert this patch.

@raziel057
Copy link

Ok thanks, in fact it's more than just a performance issue. For example I always get memory limit issues (error 500) when getting a limited list of items from a table containing a lot of data (more than 50000).

@soyuka
Copy link
Member

soyuka commented Sep 19, 2018

@raziel057 we tagged 2.3.3 without this patch and we'll try to improve it taking your inputs into consideration before it gets merged! Thanks!

@raziel057
Copy link

Thank you very much for your fast action!

@errogaht
Copy link

@soyuka fix is reverted, but I'm here because of original issue ))) I have doctrine collections with the same elements inside. Can you recommend a fix for this?

@soyuka
Copy link
Member

soyuka commented Oct 18, 2018

@soyuka fix is reverted, but I'm here because of original issue ))) I have doctrine collections with the same elements inside. Can you recommend a fix for this?

I'm really not sure how this is possible, would you mind giving me a way to reproduce?

/edit: gonna look into api-platform/api-platform#799

@soyuka
Copy link
Member

soyuka commented Oct 18, 2018

@errogaht the solution is to simply disable the eager loading feature or build your own query. I'm really not sure how we could fix this otherwise...

For the api-platform/api-platform#799 example:

/**
 * @ApiResource(
 *     attributes={"normalization_context"={"groups"={"order_read", "customer_read", "address_read"}}, "force_eager"=false}
 * )
 * @ORM\Entity
 * @ORM\Table(name="`order`")
 */
class Order
{
}

@errogaht
Copy link

errogaht commented Oct 18, 2018

$queryBuilder
        ->select('o, room_a1, floor_a2, cookRooms_a3, floor_a7, cookRooms_a8')
        ->where($queryBuilder->expr()->eq('o.id', ':id_id'))

        ->leftJoin('o.room', 'room_a1')
        ->leftJoin('room_a1.floor', 'floor_a2')
        ->leftJoin('floor_a2.cookRooms', 'cookRooms_a3')

        ->leftJoin('o.floor', 'floor_a7')
        ->leftJoin('floor_a7.cookRooms', 'cookRooms_a8')

        ->setParameter('id_id', '123')
    ;

this is the query what EagerLoadingExtension generating.
after that Floor entity have 2 elements in cookRooms collection and they are the same object

antograssiot pushed a commit to ilicmsreten/core that referenced this pull request Apr 6, 2019
antograssiot pushed a commit to ilicmsreten/core that referenced this pull request Apr 6, 2019
antograssiot pushed a commit to ilicmsreten/core that referenced this pull request Apr 6, 2019
antograssiot pushed a commit to ilicmsreten/core that referenced this pull request Apr 6, 2019
antograssiot pushed a commit to ilicmsreten/core that referenced this pull request Apr 6, 2019
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

Successfully merging this pull request may close these issues.

5 participants