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

Prepended backslash in class name reloads the full metadata from scratch #300

Closed
Tofandel opened this issue Jul 4, 2022 · 8 comments · Fixed by #301
Closed

Prepended backslash in class name reloads the full metadata from scratch #300

Tofandel opened this issue Jul 4, 2022 · 8 comments · Fixed by #301

Comments

@Tofandel
Copy link
Contributor

Tofandel commented Jul 4, 2022

Bug Report

Follow up of symfony/symfony#46837

Summary

When extracting class metadata, doctrine copies the original class data and caches it only the first time
But following that copy, calls to addEntityListener are made which are not repercuted on the alias

return $this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName];

Solution

The alias should not be copied, but should just be added to an alias map to retrieve the original cached class straight away

@stof
Copy link
Member

stof commented Jul 4, 2022

Another alternative would be to assign the metadata to the alias, but as a PHP reference rather than a copy.

@Tofandel
Copy link
Contributor Author

Tofandel commented Jul 4, 2022

Well I think that's already the case because it's an EntityMetaData instance being copied
After looking at it a bit more, it's not this line that copies it, it's actually treated as a completely different class and reloaded, hence the issue
getRealClass doesn't remove this prepended slash

So I think it's just a question of trimming this slash in getRealClass, so that it's treated as an alias instead of reloaded from scratch

@greg0ire
Copy link
Member

greg0ire commented Jul 4, 2022

Normalization seems more like the way to go yes. If I understood correctly, all this is caused because A\Class and \A\Class are equally valid ways to refer to a class. If that's indeed the issue then we should tweak our APIs so that they normalize FQCNs passed as input to just one representation.

@greg0ire
Copy link
Member

greg0ire commented Jul 4, 2022

Also, be careful when talking about aliases because in doctrine/persistence, (short) aliases mean a representation like this: My:Alias. That feature has been deprecated in #205

@Tofandel
Copy link
Contributor Author

Tofandel commented Jul 4, 2022

@greg0ire Yes exactly that

I think just this should cover it

    public function resolveClassName(string $className): string
    {
        $className = ltrim($className, '\\');
        \\...
        

Yes sorry I used alias as in class_alias, but that's not really what I'm trying to depict either, so let's completely forget about aliases as they're not relevant to this, it's 100% a FQCN with multiple possible representation issue

@Tofandel Tofandel changed the title Alias class metadata doesn't get listeners Prepended slash in class name reloads the full metadata from scratch Jul 4, 2022
@Tofandel Tofandel changed the title Prepended slash in class name reloads the full metadata from scratch Prepended backslash in class name reloads the full metadata from scratch Jul 4, 2022
@greg0ire
Copy link
Member

greg0ire commented Jul 4, 2022

Would it?

I think that wouldn't be enough to take advantage of this cache here:

if (isset($this->loadedMetadata[$className])) {
return $this->loadedMetadata[$className];
}

If you call getMetadataFor with a class name prepended with a backslash, I'd expect this condition to always fail because I would expect loadedMetadata to use normalized class names (meaning without a leading backslash) as keys.

@Tofandel
Copy link
Contributor Author

Tofandel commented Jul 4, 2022

It would take advantage of the cache on line 180 just a bit after, otherwise we can ltrim straight away $className first thing in this function

Do you know any other places where class names would be used as keys?

@greg0ire
Copy link
Member

greg0ire commented Jul 4, 2022

we can ltrim straight away $className first thing in this function

That would make a lot more sense to me.

Do you know any other places where class names would be used as keys?

That normalization should also happen in setMetadataFor and hasMetadataFor IMO.

Tofandel added a commit to Tofandel/persistence that referenced this issue Jul 4, 2022
Tofandel added a commit to Tofandel/persistence that referenced this issue Jul 5, 2022
Tofandel added a commit to Tofandel/persistence that referenced this issue Jul 5, 2022
greg0ire added a commit that referenced this issue Jul 7, 2022
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
Tofandel added a commit to Tofandel/persistence that referenced this issue Aug 6, 2022
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
Tofandel added a commit to Tofandel/persistence that referenced this issue Aug 6, 2022
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
Tofandel added a commit to Tofandel/persistence that referenced this issue Aug 6, 2022
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
Tofandel added a commit to Tofandel/persistence that referenced this issue Aug 6, 2022
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
writ3it added a commit to writ3it/persistence that referenced this issue Aug 6, 2022
fix: Normalize class names doctrine#300 (doctrine#301)

Author:  Adrien Foulon
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
Tofandel added a commit to Tofandel/persistence that referenced this issue Aug 6, 2022
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
Tofandel added a commit to Tofandel/persistence that referenced this issue Aug 6, 2022
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
writ3it added a commit to writ3it/persistence that referenced this issue Aug 6, 2022
fix: Normalize class names doctrine#300 (doctrine#301)

Author: Adrien Foulon
Co-authored-by: Adrien Foulon
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
malarzm added a commit that referenced this issue Aug 6, 2022
fix: Backport Normalize class names #300 (#301)
derrabus added a commit that referenced this issue Aug 8, 2022
* 2.5.x:
  fix: Backport Normalize class names #300 (#301)
derrabus added a commit that referenced this issue Oct 13, 2022
* 3.0.x:
  Bump CI workflow
  Allow doctrine/event-manager 2 (#310)
  Bump dev tools and CI workflows (#309)
  Identifier is a list of strings
  fix: Backport Normalize class names #300 (#301)
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 a pull request may close this issue.

3 participants