Difference between ObjectManager and EntityManager in Symfony2? - symfony

What's the difference between Doctrine\Common\Persistence\ObjectManager and Doctrine\ORM\EntityManager when using it in a custom form type?
I can get the respository using both $this->em->getRepository() and $this->om->getRepository().
class MyFormType extends \Symfony\Component\Form\AbstractType
{
/**
* #var Doctrine\ORM\EntityManager
*/
protected $em;
public function __construct(Doctrine\ORM\EntityManager $em)
{
$this->em = $em;
}
}
Instead of:
class MyFormType extends \Symfony\Component\Form\AbstractType
{
/**
* #var Doctrine\Common\Persistence\ObjectManager
*/
protected $om;
public function __construct(Doctrine\Common\Persistence\ObjectManager $om)
{
$this->om = $om;
}
}

ObjectManager is an interface and EntityManager is its ORM implementation. It's not the only implementation; for example, DocumentManager from MongoDB ODM implements it as well. ObjectManager provides only the common subset of all its implementations.
If you want your form type to work with any ObjectManager implementation, then use it. This way you could switch from ORM to ODM and your type would still work the same. But if you need something specific that only EntityManager provides and aren't planning to switch to ODM, use it instead.

Related

Symfony inject EntityManager to abstract class

i'm trying to call an utility class from a scope of a controller action.
As there will be also later another utility classes for other entites that shares some of the same dependencies, i will them extend from an abstarct class, which will be injected with entity manager.
But this doesn't work. I got for the following implementation an Exception,
""Too few arguments to function ....\Import\ImportHandle::__construct(), 0 passed in ....../Controller/ImportController.php on line 221 and exactly 1 expected""
+++++
Call from ControllerAction line 221:
$importer = new $XyImport();
+++++++
Service declaration:
...\ImportHandle:
abstract: true
public: true
arguments: ['#doctrine.orm.xy_entity_manager']
...\XyImport:
parent: ..\ImportHandle
++++++
abstract class ImportHandle
{
**
* #var EntityManager
*/
protected EntityManager $entityManager;
/**
* #param EntityManager $entityManager
*/
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
}
Really, what am i doing wrong?
Regards

references class "Doctrine\ODM\MongoDB\UnitOfWork" but no such service exists

I'm currently using Symfony 4 with Doctrine MongoDB Bundle, following the instruction from this link:
DoctrineMongoDBBundle. So, I have a UserDocument:
src/Document/UserDocument.php
/** #MongoDB\Document(collection="user", repositoryClass="App\Repository\UserRepository") */
class UserDocument
{
/**
* #MongoDB\Id
* #var ObjectId
*/
private $id;
/**
* #MongoDB\Field(type="string", name="first_name")
* #var string
*/
private $firstName;
/**
* #MongoDB\Field(type="string", name="middle_name")
* #var string
*/
private $middleName;
/**
* #MongoDB\Field(type="string", name="last_name")
* #var string
*/
private $lastName;
}
src/Repository/UserRepository.php
use Doctrine\ODM\MongoDB\DocumentRepository;
class UserRepository extends DocumentRepository
{
}
src/Controller/Content.php
class Content extends Controller
{
/**
* #Route("/content", name="content")
* #param UserRepository $user
* #return Response
*/
public function index(UserRepository $user)
{
$user->findAll();
return new Response();
}
}
So, after running the content page, I got the following error:
Cannot autowire service "App\Repository\UserRepository": argument "$uow" of method "__construct()" references class "Doctrine\ODM\MongoDB\UnitOfWork" but no such service exists.
The DocumentRepository constructor looks like this:
public function __construct(DocumentManager $dm, UnitOfWork $uow, ClassMetadata $classMetadata)
{
parent::__construct($dm, $uow, $classMetadata);
}
Repository shouldn't be Services, but if you want to keep it that way, just Autowire the DocumentManager and get the uow and classmetdata from the Document Manager.
UnitOfWork and ClassMetadata can't be autowired
Do something like that in your UserRepository, it should work.
public function __construct(DocumentManager $dm)
{
$uow = $dm->getUnitOfWork();
$classMetaData = $dm->getClassMetadata(User::class);
parent::__construct($dm, $uow, $classMetaData);
}
Make sure to exclude your repository class from autowiring. Example here: https://symfony.com/doc/current/service_container/3.3-di-changes.html
In case you want your repository class as a service you should do it using a factory service.

Symfony3 Use Entity Manager in Custom Container

I want to create HelperController for my project. I generate a controller with doctrine:generate:controller and I need to use entity manager in it.
I enjected to services.yml but it is giving an error like this:
Argument 1 passed to CampingBundle\Controller\HelperController::__construct() must be an instance of Doctrine\ORM\EntityManager, none given ...
My Controller Code :
namespace CampingBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Doctrine\ORM\EntityManager;
class HelperController extends Controller
{
protected $manager;
public function __construct(EntityManager $manager)
{
$this->manager = $manager;
}
My Services.yml :
services:
camping.helper_controller:
class: CampingBundle\Controller\HelperController
arguments: ["#doctrine.orm.entity_manager"]
Why it doesn't work ? Shoudl I clear cache or something else or is there anything wrong in definition ?
Thanks
Try to use EntityManagerInterface and remove extends Controller.
Check this link if you need CAS (Controllers as Services).
Change protected $manager; to private $manager;
namespace CampingBundle\Controller;
use Doctrine\ORM\EntityManagerInterface;
class HelperController
{
/**
* #var EntityManagerInterface $entityManager
*/
private $entityManager;
/**
* #param $entityManager
*/
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
}
I'll leave my two cents here as I had same issue and fixed it by adding tags to service.
something.validate.some_service:
class: Path\To\Some\Validator
arguments:
- '#doctrine.orm.entity_manager'
tags:
- { name: validator.constraint_validator, alias: some_validator_alias }
How to Work with Service Tags by Symfony

Symfony2, use getDoctrine and em in class

I have a Timesheet.php class in Symfony2, and i need, in this class, use for example :
$this->getDoctrine()->getRepository()->find();
$this->getDoctrine()->getManager()->remove();
How can i do that ? I have try to call the class as a service, manually add variable in constructor and other but no effect...
Do you have a good solution ?
This is because $this->getDoctrine() is method of Symfony\Bundle\FrameworkBundle\Controller class. When you check this method there is $this->container->get('doctrine') so what you need is having doctrine available in your Timesheet class. To do so, define your Timesheet class as a service:
your.service_id:
class: Acme\DemoBundle\Timesheet
arguments: [#doctrine]
Then your Timesheet class:
use Doctrine\Bundle\DoctrineBundle\Registry;
class Timesheet
{
/**
* #var Registry
*/
private $doctrine;
/**
* #param Registry $doctrine Doctrine
*/
public function __construct(Registry $doctrine)
{
$this->doctrine = $doctrine;
}
public function yourMethod()
{
//this is what you want to achieve, right?
$this->doctrine->getManager()->remove();
$this->doctrine->getRepository()->find();
}
}

Symfony2 how to get the Doctrine EntityManager from a generic object

I have an object from inside a Symfony2 project. Here follows the code.
namespace Acme\UserBundle\Form\Model;
use Symfony\Component\Validator\Constraints as Assert;
use Acme\UserBundle\Entity\User;
class Registration
{
/**
* #Assert\Type(type="Acme\UserBundle\Entity\User")
*/
protected $user;
...
public function setUser(User $user)
{
//Get the EntityManager here!!!!
$group = $em
->getRepository('AcmeUserBundle:Group')
->findOneByName('Customers');
$this->user->addGroup($group);
}
....
}
So, as highlighted in the code, how to get the EntityManager to retrieve an entity with Doctrine?
Thanks in advance
Ok, solved!
I only have to pass the EntityManager to the constructor of the Registration class within the controller.
use Symfony\Component\Validator\Constraints as Assert;
use Acme\UserBundle\Entity\User;
class Registration
{
/**
* #Assert\Type(type="Acme\UserBundle\Entity\User")
*/
protected $user;
...
protected $em;
public function __construct($em) {
$this->em = $em;
}
public function setUser(User $user)
{
$this->user = $user;
$group = $this->em->getRepository('AcmeUserBundle:Group')
->findOneByName('Customers');
$this->user->addGroup($group);
}
...
}
Thanks a lot anyway.

Resources