dougu2036
2015-08-07 19:02
浏览 68
已采纳

我究竟如何在Symfony2 / Doctrine中创建自定义EntityManager?

New guy at Symfony/Doctrine. So kindly guide me.

Requirement: To create a custom EntityManager which would override some of the methods like remove (instead of remove, i want to perform an update and modify a parameter like isValid in my class, so that the records are never deleted) and a find ( find a record which has a non zero isValid ) etc and use it instead of Doctrine's EntityManager.

I started reading through this thread: Is there a way to specify Doctrine2 Entitymanager implementation class in Symfony2? and found the answer by user2563451 to be not so straightforward. I got lost when he talks about not to follow certain approaches (again no location of the files to be modified).

I have looked at the EntityManager.php and it specifically tells not to use extend the EntityManager class. Rather it asks to extend the EntityManagerDecorator. On looking at the EntityManagerDecorator, there are no methods available inside it (like create, persist, etc which I found in EntityManager) Does it mean I need to create new methods for each and every single Entity Manager functionality ?

Since there is no clear defined way to get this done, I am confused to get this thing started. Also Doctrine cookbook is of little use to me as it does not have any information to achieve this.

So any help regarding the extending of EntityManagerDecorator or EntityManager is appreciated.

Best if you can provide me step by step directions to achieve the same.

Thanks !

Edit 1: my requirement is to use my custom EntityManager instead of Doctrine's EntityManager (EM) and modify those 'remove' and 'find' methods as per my requirements. I am not sure whether I need to reuse the functionality provided by Doctrine's EM or write from scratch.

图片转代码服务由CSDN问答提供 功能建议

Symfony / Doctrine的新人。 亲切地指导我。

要求:要创建一个自定义的EntityManager,它会覆盖一些方法,比如删除(而不是删除,我想在我的类中执行更新并修改像isValid这样的参数,这样 记录永远不会删除)和查找(找到一个非零isValid的记录)等,并使用它而不是Doctrine的EntityManager。

我开始阅读这个帖子: < a href =“https://stackoverflow.com/questions/8138962/is-there-a-way-to-specify-doctrine2-entitymanager-implementation-class-in-symfon”>有没有办法指定Doctrine2 Entitymanager实现 在Symfony2中的类?并发现user2563451的答案并不那么简单。 当他谈到不遵循某些方法时,我迷路了(再次没有要修改的文件的位置)。

我查看了EntityManager.php,它特别指出不要使用扩展EntityManager类。 而是要求扩展EntityManagerDecorator。 在查看EntityManagerDecorator时,其中没有可用的方法(比如我在EntityManager中找到的create,persist等)是否意味着我需要为每个Entity Manager功能创建新方法?

由于没有明确的方法来完成这项工作,我很困惑,让这件事情开始了。 另外,Doctrine cookbook对我来说没有多大用处,因为它没有任何信息可以实现这一点。

因此,有关扩展EntityManagerDecorator或EntityManager的任何帮助都表示赞赏。

如果你能为我提供一步一步的指导,那就最好了。

谢谢!

编辑1:我的要求是使用我的自定义EntityManager而不是Doctrine的EntityManager(EM),并根据我的要求修改那些'remove'和'find'方法。 我不确定是否需要重用Doctrine EM提供的功能或从头开始编写。

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • douqianbiao4216 2015-08-07 19:29
    已采纳

    I think you may be confusing a Manager with a Repository.

    An EntityManager is really nothing more than a Service you use to manage that specific or a collection of entities.

    A repository extends \Doctrine\ORM\EntityRepository and is what tells Doctrine how to store your entity in the database.

    You can use the combination of these two to achieve what you want.

    For example. Let's take our entity Foo

    class Foo
    {
        //...other properties
    
        protected $isValid;
    
        //...Getters and setters
    }
    

    We then have a manager for Foo.

    class FooManager
    {
        protected $class;
        protected $orm;
        protected $repo;
    
        public function __construct(ObjectManager $orm , $class)
        {
            $this->orm = $orm;
            $this->repo = $orm->getRepository($class);
    
            $metaData = $orm->getClassMetadata($class);
            $this->class = $metaData->getName();
        }
    
        public function create()
        {
            $class = $this->getClass();
            $foo = new $class;
    
            return $foo;
        }
    
        public function findBy(array $criteria)
        {
            return $this->repo->findOneBy($criteria);
        }
    
        public function refreshFoo(Foo $foo)
        {
            $this->orm->refresh($foo);
        }
    
        public function updateFoo(Foo $foo, $flush = true)
        {   
            $this->orm->persist($foo);
            if($flush)
            {
                $this->orm->flush();
            }
        }
    
        public function getClass()
        {
            return $this->class;
        }
    }
    

    We have some basic functions for Creating and Updating our object. And now if you wanted to "remove" it without actually deleting it, you can add the following function in the Manager.

    public function remove(Foo $foo)
    {
        $foo->setIsValid(false);
        return $this->update($foo);
    }
    

    This way, we update the isValid fields to false and persist it to the database. And you'd use this like any service inside your controller.

    class MyController extends Controller
    {
        public function someAction()
        {
            $fooManager = $this->get('my_foo_manager');
            $newFoo = $fooManager->create();
    
            //...
            $fooManager->remove($newFoo);
        }
    }
    

    So now we've got the remove part.

    Next, we only want to find entities that isValid set to TRUE.

    Honestly, the way I'd handle this is not even modify the find and instead in your controller

    if(!$foo->getIsValid())
    {
        //Throw some kind of error.  Or redirect to an error page.
    }
    

    But if you want to do it the other way. You can just make a repo.

    use Doctrine\ORM\EntityRepository;
    class FooRepository extends EntityRepository
    {
        public function find($id, $lockMode = LockMode::NONE, $lockVersion = null)
        {
            //Some custom doctrine query.
        }
    }
    

    We override EntityRepository's native find() function with our own.

    Finally we get all of this registered in the right places. For the manager you've got to make a service.

    services:
        my_foo_manager:
            class: AppBundle\Manager\FooManager
            arguments: [ "@doctrine.orm.entity_manager" , 'AppBundle\Entity\Foo']
    

    And for the repository, you must specify the repositoryClass in the ORM definition of your entity.

    AppBundle\Entity\Foo:
        type: entity
        repositoryClass: AppBundle\Entity\FooRepository
        table: foos
        id:
            id:
                type: integer
                generator: {strategy: AUTO}
                options: {unsigned: true}
        fields:
            isValid:
                type: boolean
    

    Knowing all of this you can now do some pretty cool things with Entities. I hope this helped. Good luck!

    已采纳该答案
    打赏 评论
  • dourui7186 2015-08-07 20:55

    Regarding your use cases, you should instead use Doctrine Lifecycle Callbacks for the remove case and simple overide the find method in your entity repository.

    打赏 评论

相关推荐 更多相似问题