在实体中获取entityManager [英] Get entityManager inside an Entity

查看:124
本文介绍了在实体中获取entityManager的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用,例如:

  $ em = $ this-> getEntityManager(); 

实体内。



我明白我应该做这个服务,但为了某些测试目的,我想从一个实体访问它。



是否可以实现?



我试图:

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

但不行。


致命错误:调用未定义的方法

/ opt / lampp / htdocs / web中的Proxies\webBundleEntityUserProxy :: getEntityManager() /src/Pct/bundle/Entity/User.php
449


为什么要这样做?



我有3种用户:Facebook,Twitter和MyOwnWebsite用户。每个人都有不同的头像,链接Facebook的个人资料,微博或其他,如果它的myownwebsite用户,我从数据库中的URL检索头像。现在,我不想创建一个服务,因为我只是试图让它工作,测试它,而不是创建最终的部署。所以这就是为什么我试图从实体调用实体经理。现在我不想修改配置文件,只是这个实体。

解决方案

正如一个评论者,一个实体内的实体经理是一个代码气味。对于OP的具体情况,他希望收购实体经理,最不重要的是,简单的注入将是最可靠的(与我通过构造函数注入的原始示例相反)。



对于其他任何人来说,寻找同样问题的卓越解决方案,有两种方法可以实现:


  1. 根据 https://stackoverflow.com/建议的 c>实现 ObjectManagerAware a / 24766285/1349295

     使用Doctrine\Common\Persistence\ObjectManagerAware; 
    使用Doctrine\Common\Persistence\ObjectManager;
    使用Doctrine\Common\Persistence\Mapping\ClassMetadata;
    使用Doctrine\ORM\Mapping作为ORM;

    / **
    * @ ORM\Entity
    * /
    class Entity implements ObjectManagerAware
    {
    public function injectObjectManager(
    ObjectManager $ objectManager,
    ClassMetadata $ classMetadata
    ){
    $ this-> em = $ objectManager;
    }
    }


  2. 或使用 @postLoad / @postPersist 生命周期回调并使用 LifecycleEventArgs 参数由 https://stackoverflow.com/a/23793897/1349295 建议

     使用Doctrine\Common\Persistence\Event\LifecycleEventArgs; 
    使用Doctrine\ORM\Mapping作为ORM;

    / **
    * @ ORM\Entity
    * @ ORM\HasLifecycleCallbacks()
    * /
    class Entity
    {
    / **
    * @ ORM\PostLoad
    * @ ORM\PostPersist
    * /
    public function fetchEntityManager(LifecycleEventArgs $ args)
    {
    $ this-> setEntityManager($ args-> getEntityManager());
    }
    }




原始答案



Entity EntityManager >是非常恶劣的做法。但是,如果你真的真的需要一个实体的实体管理器,不能做这样的事情。否则将其注入实体。

  class Entity 
{
private $ em;

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

然后调用为新实体($ em)


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 Proxies\webBundleEntityUserProxy::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.

解决方案

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 Doctrine\Common\Persistence\ObjectManagerAware;
    use Doctrine\Common\Persistence\ObjectManager;
    use Doctrine\Common\Persistence\Mapping\ClassMetadata;
    use Doctrine\ORM\Mapping as ORM;
    
    /**
     * @ORM\Entity
     */
    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 Doctrine\Common\Persistence\Event\LifecycleEventArgs;
    use Doctrine\ORM\Mapping as ORM;
    
    /**
     * @ORM\Entity
     * @ORM\HasLifecycleCallbacks()
     */
    class Entity
    {
        /**
         * @ORM\PostLoad
         * @ORM\PostPersist
         */
        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).

这篇关于在实体中获取entityManager的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆