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

#6217 #6284 when hydrating an entity with a composite primary key that is both an EAGER and a LAZY association and also cached, the DefaultQueryCache tries to pass L2 cache implementation detail objects to the UnitOfWork #6640

Conversation

Ocramius
Copy link
Member

Fixes #6217
Fixes #6284

This is a proper version of #6284, fixing the deeper problem.

Basically, what is happening is that you have a L2 cached entity class like following:

class A
{
    /** @Id @ManyToOne(targetEntity=b) */
    private $b;
    /** @Id @ManyToOne(targetEntity=c)*/
    private $c;
}

And a DQL query like following:

SELECT a, b
FROM A a
JOIN a.b b

The L2 cache for A.c won't have any information to cache, but it will still contain the identifier for A.c. This means that for that association, a AssociationCacheEntry exists anyway, but no definition in the QueryCacheEntry on how to process it.

I also tried fixing the problem on the other side (where the QueryCacheEntry is produced, rather than consumed), but overfitting it when no association data is actually available causes empty AssociationCacheEntry objects to be hydrated into empty entities (really bad!).

This is just a shotgun patch to fix the problem by iterating over all possible association fields, so if you have any better ideas, please do let me know.

gadelkareem and others added 16 commits August 22, 2017 19:45
…ching issue.

We are not hydrating some of the cached association data into entities due to keys missing in the cache association definition.
Since this is an extreme edge case that is just a mismatch between db and cache, a detailed explanation was provided in the fix snippet as well
…id fix that was actually fixing the symptom
/* @var $found GH6217FetchedEntity[] */
$found = $repository->findBy($filters);

$this->assertCount(1, $found);
Copy link
Member

Choose a reason for hiding this comment

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

self::

//
// We need to unwrap those associations into proxy references,
// since we don't have actual data for them except for identifiers.
if ($unCachedAssociationData instanceof AssociationCacheEntry) {
Copy link
Member

@lcobucci lcobucci Aug 23, 2017

Choose a reason for hiding this comment

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

It makes sense IMO, but I feel like we could do that conversion while iterating $entry['associations'] in https://github.com/doctrine/doctrine2/pull/6640/files#diff-c5343cb0b202102a59de56dfdcb8ee47R147 to avoid looping over the entire object data.

Copy link
Member Author

Choose a reason for hiding this comment

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

$entry['associations'] does not contain the keys we're iterating upon here.

I considered using an accumulator of already processed keys, but since these are usually about associations, and the number of fields and associations is (typically) < 10 on any entity, looping is actually faster than aggregating the keys and excluding them here.

@Ocramius
Copy link
Member Author

🚢

@Ocramius Ocramius assigned Ocramius and unassigned lcobucci Aug 25, 2017
@Ocramius Ocramius merged commit 61404e2 into master Aug 25, 2017
@Ocramius Ocramius deleted the fix/#6284-#6217-avoid-passing-l2-cache-information-internals-to-the-uow branch August 25, 2017 07:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants