Orm: EntityManagerDecorator's repositories use EntityManager

Created on 11 May 2016  路  7Comments  路  Source: doctrine/orm

Repositories created by Doctrine\ORM\Decorator\EntityManagerDecorator use EntityManager instead of EntityManagerDecorator:

use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Decorator\EntityManagerDecorator;

$entityManager = EntityManager::create($dbParams, $config);
$entityManager->getRepository('entity')->getEntityManager();
// returns: Doctrine\ORM\EntityManager

class TestDecorator extends EntityManagerDecorator 
{
    // ...
}

$decorator = new TestDecorator($entityManager);
$decorator->getRepository('entity')->getEntityManager();
// returns: Doctrine\ORM\EntityManager
// expected: TestDecorator ?

This behavior may be unexpected for custom repositories using decorator object.

Improvement

Most helpful comment

Actually it does have a workaround:

```php
class CustomDecorator extends EntityManagerDecorator {

protected $repositoryFactory;

// In Symfony 2.* $config can be injected with @doctrine.orm.default_configuration
public function __construct(EntityManagerInterface $wrapped, Configuration $config)
{
    $this->repositoryFactory = $config->getRepositoryFactory();
    parent::__construct($wrapped);
}


/**
 * Gets the repository for an entity class.
 *
 * Fixes: https://github.com/doctrine/doctrine2/issues/5820
 *
 * @param string $entityName The name of the entity.
 *
 * @return \Doctrine\ORM\EntityRepository The repository class.
 */
public function getRepository($entityName)
{
    return $this->repositoryFactory->getRepository($this, $entityName);
}

}

All 7 comments

Hello, I'm afraid this is not something we can fix. Since we're talking about decorator pattern, inner EM instance has no knowledge about being decorated. One possible solution would be using RepositoryFactory that is created for your decorator, not for inner EM by default.

Just to give people reading this a well visible notice.

There is a similar issue to this one with transactional method: https://github.com/doctrine/doctrine2/issues/7161

The difference is that #7161 can workaround it, while this one cannot

I think event objects will also have the inner EM (as well as any place receiving the EM from the EM itself as $this)

Actually it does have a workaround:

```php
class CustomDecorator extends EntityManagerDecorator {

protected $repositoryFactory;

// In Symfony 2.* $config can be injected with @doctrine.orm.default_configuration
public function __construct(EntityManagerInterface $wrapped, Configuration $config)
{
    $this->repositoryFactory = $config->getRepositoryFactory();
    parent::__construct($wrapped);
}


/**
 * Gets the repository for an entity class.
 *
 * Fixes: https://github.com/doctrine/doctrine2/issues/5820
 *
 * @param string $entityName The name of the entity.
 *
 * @return \Doctrine\ORM\EntityRepository The repository class.
 */
public function getRepository($entityName)
{
    return $this->repositoryFactory->getRepository($this, $entityName);
}

}

And then you find that SQLBuilder also has a wrapped entity manager instance, you fix that, only to find that all collections also have the wrapped instance embedded. In the end, there is no point in using a decorated entity manager because of that because it's impossible to make it work.

Any workaround for getting the decorator in lifecycle callbacks?

Was this page helpful?
0 / 5 - 0 ratings