Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the EntityManager in Symfony 3, correctly?

I am using current versions of Symfony (3.2.3) and Doctrine ORM (2.5.6) and I'm still trying to wrap my head around how to handle the deprecation of getEntityManager() and related methods correctly.

For instance, the current documentation states that this is the way to create a query builder instance:

$repository = $this->getDoctrine()->getRepository('AppBundle:Product');
$queryBuilder = $repository->createQueryBuilder('p')

But the way I see it (and my IDE seems to agree), getRepository() is type hinted to return an instance of ObjectRepository and the method createQueryBuilder() is not declared in that interface but in the implementing class EntityRepository.

An other example would be explicitly starting a transaction in a controller:

$this->getDoctrine()->getEntityManager()->getConnection()->beginTransaction()

I'm supposed to call getManager() instead of getEntityManager() because the latter method is deprecated. But getManager() is type hinted to return an instance of ObjectManager which does not declare getConnection().

PHP being PHP the code still seems to be working in all cases, but my IDE and I are left with an uneasy feeling. So, what is the correct way to create a query builder or begin a transaction in Symfony 3? Am I missing something?

like image 444
cg. Avatar asked Feb 08 '17 13:02

cg.


People also ask

How should be the process to add a new entity to the app in Symfony?

With the doctrine:database:create command we create a new database from the provided URL. With the make entity command, we create a new entity called City . The command creates two files: src/Entity/City. php and src/Repository/CityRepository.

Why is EntityManager closed?

Having a failure at DB level during the transaction (in your try { }) will cause the EntityManager to be closed.

What is a entity in Symfony?

Well, entity is a type of object that is used to hold data. Each instance of entity holds exactly one row of targeted database table. As for the directories, Symfony2 has some expectations where to find classes - that goes for entities as well.

What is Doctrine in Symfony?

Symfony provides all the tools you need to use databases in your applications thanks to Doctrine, the best set of PHP libraries to work with databases. These tools support relational databases like MySQL and PostgreSQL and also NoSQL databases like MongoDB.


1 Answers

Doctrine has a two types of Data Mappers: the ORM for the RDBMS and the ODM for document-oriented DBs (mostly for MongoDB). Data mappers try to achieve in a sort of persistence-ignorance and both of them implements a generic interfaces defined in the Doctrine\Common, such as ObjectManager or ObjectRepository.

In the Symfony the getDoctrine() method returns an instance of Registry class from the DoctrineBundle (by default). In short this service holds all available connections and entity managers. His method getManager() implemented in the Doctrine\Common, it don't knows what type of data mapper and declares return type as generic ObjectManager.

To avoid IDE warnings you can explicitly define the inline PHPDoc. Netbeans and PHPStorm are support it.

/* @var $entityManager Doctrine\ORM\EntityManager */
$entityManager = $this->getDoctrine()->getManager();

Other solution is a simple helper method:

public function getEntityManager(): EntityManager
{
    return $this->getDoctrine()->getManager();
}

With above solutions we assume that requested service is actually from the ORM, so is a sort of type downcasting: actual class will be checked only in runtime. For the type-safety you can directly inject the entity manager in the your service.

like image 138
Timurib Avatar answered Sep 30 '22 01:09

Timurib