Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
837 views
in Technique[技术] by (71.8m points)

symfony - Get entityManager inside an Entity

I'd like to use, something like:

$em = $this->getEntityManager();

Inside a Entity.

I understand I should do this as a service but for some testing purposes, I want to access it from an Entity.

Is it possible to achieve that?

I've tried to:

$em = $this->getEntityManager();
$profile_avatar = $em->getRepository('bundle:Perfils')->findOneByUser($this-getId());

But isn't working.

Fatal error: Call to undefined method ProxieswebBundleEntityUserProxy::getEntityManager() in /opt/lampp/htdocs/web/src/Pct/bundle/Entity/User.php on line 449

Why am I trying to do it this way?

I've 3 kinds of users: Facebook, Twitter and MyOwnWebsite users. Each of them have differents avatar which links facebook's profile, twitter's or otherwise, if its myownwebsite user, I retrieve the avatar from a URL in a database. For now, I don't want to create a service, because I'm just trying to make it working, to test it, not to create a final deployment. So this is why I'm trying to call Entity manager from an Entity. I don't want, by now, to modify configuration files, just this entity.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As pointed out (again) by a commenter, an entity manager inside an entity is a code smell. For the OP's specific situation where he wished to acquire the entity manager, with the least bother, a simple setter injection would be most reliable (contrary to my original example injecting via constructor).

For anyone else ending up here looking for a superior solution to the same problem, there are 2 ways to achieve this:

  1. Implementing the ObjectManagerAware interface as suggested by https://stackoverflow.com/a/24766285/1349295

    use DoctrineCommonPersistenceObjectManagerAware;
    use DoctrineCommonPersistenceObjectManager;
    use DoctrineCommonPersistenceMappingClassMetadata;
    use DoctrineORMMapping as ORM;
    
    /**
     * @ORMEntity
     */
    class Entity implements ObjectManagerAware
    {
        public function injectObjectManager(
            ObjectManager $objectManager,
            ClassMetadata $classMetadata
        ) {
            $this->em = $objectManager;
        }
    }
    
  2. Or, using the @postLoad/@postPersist life cycle callbacks and acquiring the entity manager using the LifecycleEventArgs argument as suggested by https://stackoverflow.com/a/23793897/1349295

    use DoctrineCommonPersistenceEventLifecycleEventArgs;
    use DoctrineORMMapping as ORM;
    
    /**
     * @ORMEntity
     * @ORMHasLifecycleCallbacks()
     */
    class Entity
    {
        /**
         * @ORMPostLoad
         * @ORMPostPersist
         */
        public function fetchEntityManager(LifecycleEventArgs $args)
        {
            $this->setEntityManager($args->getEntityManager());
        }
    }
    

Original answer

Using an EntityManager from within an Entity is VERY BAD PRACTICE. Doing so defeats the purpose of decoupling query and persist operations from the entity itself.

But, if you really, really, really need an entity manager in an entity and cannot do otherwise then inject it into the entity.

class Entity
{
    private $em;

    public function __contruct($em)
    {
        $this->em = $em;
    }
}

Then invoke as new Entity($em).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...