Skip to content

[DoctrineBridge] Inject the entity manager instead of the class metadata factory in DoctrineExtractor #27829

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

Conversation

dunglas
Copy link
Member

@dunglas dunglas commented Jul 3, 2018

Q A
Branch? master
Bug fix? no
New feature? no
BC breaks? no
Deprecations? yes
Tests pass? yes
Fixed tickets n/a
License MIT
Doc PR symfony/symfony-docs#10311

As explained by @stof in #27735 (comment), injecting the ClassMetadataFactory directly can lead to issues when resetting the EntityManager.

This PR deprecates this usage and encourages to inject the entity manager directly.

4.2.0
-----

* deprecated injection `ClassMetadataFactory` in `DoctrineExtractor`,
Copy link
Member

Choose a reason for hiding this comment

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

injecting

-----

* deprecated injection `ClassMetadataFactory` in `DoctrineExtractor`,
and instance of `EntityManagerInterface` must be injected instead
Copy link
Member

Choose a reason for hiding this comment

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

s/and/an
s/must/should (friendlier)

private $classMetadataFactory;

public function __construct(ClassMetadataFactory $classMetadataFactory)
/**
* @param EntityManagerInterface|ClassMetadataFactory $entityManager
Copy link
Member

Choose a reason for hiding this comment

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

should document only the not-deprecated type

if ($entityManager instanceof EntityManagerInterface) {
$this->entityManager = $entityManager;
} else {
@trigger_error(sprintf('Injecting an instance of "%s" in "%s" is deprecated since version 4.2 and will not be possible anymore in 5.0. Inject an instance of "%s" instead.', ClassMetadataFactory::class, __CLASS__, EntityManagerInterface::class), E_USER_DEPRECATED);
Copy link
Member

Choose a reason for hiding this comment

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

Injecting an instance of "%s" in "%s" is deprecated since Symfony 4.2, inject an instance of "%s" instead.

@dunglas dunglas force-pushed the pinfo-deprecate-inject-metadata-factory branch from ce4511b to 968d75a Compare July 3, 2018 20:08
$this->classMetadataFactory = $classMetadataFactory;
if ($entityManager instanceof EntityManagerInterface) {
$this->entityManager = $entityManager;
} else {
Copy link
Member

Choose a reason for hiding this comment

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

elseif ($entityManager instanceof ClassMetadataFactory) and then we should add an else block that throws an InvalidArgumentException for everything else

Copy link
Member Author

Choose a reason for hiding this comment

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

We don't check for invalid types when documented in the DockBlock, do we?

Copy link
Member

Choose a reason for hiding this comment

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

For other places where we deprecated arguments and removed the type hint we added them.

@xabbuh
Copy link
Member

xabbuh commented Jul 6, 2018

How will this behave when you have more than one entity manager configured? Right now the entity manager just forwards the call so there is no difference. But is this assumption future proof?

@dunglas
Copy link
Member Author

dunglas commented Jul 6, 2018

There is a different metadata factory for every entity manager, so I don't think it can be an issue.

@@ -40,7 +50,7 @@ public function __construct(ClassMetadataFactory $classMetadataFactory)
public function getProperties($class, array $context = array())
{
try {
$metadata = $this->classMetadataFactory->getMetadataFor($class);
$metadata = $this->entityManager ? $this->entityManager->getClassMetadata($class) : $this->classMetadataFactory->getMetadataFor($class);
Copy link
Contributor

Choose a reason for hiding this comment

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

what about extracting private method for that?

Copy link
Member Author

Choose a reason for hiding this comment

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

It doesn't worth it: it will introduce a performance penalty and anyway it will be dropped in Symfony 5.

@chalasr
Copy link
Member

chalasr commented Jul 9, 2018

UPGRADE files need to be updated

Copy link
Member

@fabpot fabpot left a comment

Choose a reason for hiding this comment

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

Can you a note in the UPGRADE file?

@dunglas dunglas force-pushed the pinfo-deprecate-inject-metadata-factory branch from 968d75a to 9e05506 Compare July 13, 2018 11:57
@@ -27,11 +28,22 @@
*/
class DoctrineExtractor implements PropertyListExtractorInterface, PropertyTypeExtractorInterface
{
private $entityManager;
private $classMetadataFactory;
Copy link
Contributor

@ro0NL ro0NL Jul 13, 2018

Choose a reason for hiding this comment

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

should this one have a @deprecated tag?

Copy link
Member

Choose a reason for hiding this comment

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

I don't think so, it's a private property anyway

Copy link
Member

Choose a reason for hiding this comment

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

It might help at time to clean up deprecated features from the next major branch.
With some well placed @deprecated flags for each deprecated feature, cleaning an entire component can be way easier (just greping) and free of leftovers (each one leading to "drop dead code" PRs, you know).

Copy link
Contributor

Choose a reason for hiding this comment

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

that, and the fact it hints to not use the property anymore

@fabpot fabpot force-pushed the pinfo-deprecate-inject-metadata-factory branch from 262906b to 3aab4a1 Compare July 13, 2018 20:22
@fabpot
Copy link
Member

fabpot commented Jul 13, 2018

Thank you @dunglas.

@fabpot fabpot merged commit 3aab4a1 into symfony:master Jul 13, 2018
fabpot added a commit that referenced this pull request Jul 13, 2018
…the class metadata factory in DoctrineExtractor (dunglas)

This PR was squashed before being merged into the 4.2-dev branch (closes #27829).

Discussion
----------

[DoctrineBridge] Inject the entity manager instead of the class metadata factory in DoctrineExtractor

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  |no <!-- don't forget to update src/**/CHANGELOG.md files -->
| BC breaks?    | no     <!-- see https://symfony.com/bc -->
| Deprecations? | yes <!-- don't forget to update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tests pass?   | yes    <!-- please add some, will be required by reviewers -->
| Fixed tickets | n/a   <!-- #-prefixed issue number(s), if any -->
| License       | MIT
| Doc PR        | n/a

As explained by @stof in #27735 (comment), injecting the `ClassMetadataFactory` directly can lead to issues when resetting the EntityManager.

This PR deprecates this usage and encourages to inject the entity manager directly.

Commits
-------

3aab4a1 [DoctrineBridge] Inject the entity manager instead of the class metadata factory in DoctrineExtractor
@dunglas dunglas deleted the pinfo-deprecate-inject-metadata-factory branch September 10, 2018 14:55
javiereguiluz added a commit to symfony/symfony-docs that referenced this pull request Sep 11, 2018
…class metadata factory (dunglas, javiereguiluz)

This PR was merged into the master branch.

Discussion
----------

[PropertyInfo] Inject the entity manager instead of the class metadata factory

symfony/symfony#27829

Commits
-------

44df1a7 Added the missing versionadded directive
1f87e0c [PropertyInfo] Inject the entity manager instead of the class metadata factory
@nicolas-grekas nicolas-grekas modified the milestones: next, 4.2 Nov 1, 2018
This was referenced Nov 3, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants