Symfony2 entityManager in model

12,388

Solution 1

First, a starting note: by convention your Entity class should probably be singular. So, Setting, not Settings. You could argue that "settings" as a group of related settings could be seen as one entity. Still, something to bear in mind.

In Doctrine2, you would use a repository to make this type of query. In your code where you were going to call Settings::getParam, you would instead fetch the repository and query that. In symfony2, say:

// $em is your entitymanager, as you were going to pass to your method above
// $key is the key you were going to pass to your method above
$repository = $em->getRepository('\FrontendBundle\Settings');
$setting = $repository->getByParam($key);

By default, without writing any code, repositories define getByXXXX for each field in your entity.

If you have a more complicated query to make, you can extend the repository.

use Doctrine\ORM\EntityRepository;

class SettingsRepository extends EntityRepository 
{
    public function getBySomeComplicatedQuery() {
        $sort_order = $this->getEntityManager()
            ->createQuery('SELECT count(s) FROM FrontendBundle\Settings s WHERE s.value > 32')
            ->getResult(Query::HYDRATE_SINGLE_SCALAR);
    }

}

And then you'd call that method in the same way.

Others would advocate the use of a Manager object which would then not be tied to the Entity/ORM, but that's a needless complication in this case I think.

Doctrine2 is specifically designed to not let you use queries in your Entity file; Entities and EntityManagers are actually two aspects of the standard model layer, split apart to enforce best practices. See this article: http://symfony2basics.jkw.co.nz/get-symfony2-working/entities/

Solution 2

Queries in the Entity class

Putting queries in you entity seems odd to me. The same way as putting queries into your model class in Doctrine 1 it is not considered a good practice. Entity classes should be light.

I'm actually learning Doctrine2 and was thinking about similar problem: where to put queries?

In Doctrine 1 there are special Table classes and I was expecting something similar in Doctrine 2.

Repository Pattern

Today I learned that Doctrine 2 is using the Repository Pattern: http://www.doctrine-project.org/docs/orm/2.0/en/reference/working-with-objects.html#custom-repositories

However, to retrieve an instance of repository class you need to use Entity Manager. One way or another you need it.

Still, following the repository pattern seems a better choice.

In my opinion If you insist on having query method in your Entity class you have to pass an Entity Manager to it.

Testing

Why the need of passing entity manager makes it hard to test? From my experience explicit dependencies make testing easier as you can control them in the test (and mock them for example).

On the other hand passing the entity manager to every method is not right choice either. In such case I'd make the dependency obligatory and add it to the contructor.

Share:
12,388

Related videos on Youtube

Aleksei Kornushkin
Author by

Aleksei Kornushkin

Updated on November 13, 2020

Comments

  • Aleksei Kornushkin
    Aleksei Kornushkin over 3 years

    I'm going to use entity_manager in my model. But entity_manager is only available in controller: throw $em = $this->get('doctrine.orm.entity_manager'). So, I have to define model methods with $em parameter. This is making phpUnit testing pretty difficult and violates application structure. For example:

    class Settings
    {
        public static function getParam( $em, $key )
        {
            $em->createQuery("
                SELECT s
                FROM FrontendBundle:Settings s
                WHERE s.param = {$key}
            ");
            return $em->getResult();
        }
    }
    

    Is there any approach to use entity_manager service in model section?

  • userfuser
    userfuser over 7 years
    Hi, the last link is gone.

Related