分离和序列化学说实体

时间:2013-10-04 16:17:11

标签: php symfony serialization doctrine-orm entities

我的问题引用了Doctrine many-to-many relations and onFlush event

enter image description here

作者权利:http://pastebin.com/GBCaSA4Z 图书实体:http://pastebin.com/Xb2SEiaQ

我运行此代码:

    $book = new \App\CoreBundle\Entity\Books();
    $book->setTtile('book title: '.uniqid());
    $book->setIsbn('book isbn: '.uniqid());

    $author = new \App\CoreBundle\Entity\Authors();
    $author->setName('author title: '.uniqid());

    $author->addBook($book);

    $entityManager->persist($author);


    $entityManager->flush();

这样一切都好。 Doctrine生成三个查询:创建作者,创建书籍并在author_books创建链接。

但我需要在 onFlush 事件中分离并序列化所有实体,并将它们保存在NoSQL数据库中。然后其他脚本将反序列化所有这些实体并将它们保存到数据库。通过这种方式,Doctrine只生成两个SQL查询:创建书籍和创建作者。我应该对doctrine做什么也为链接表生成SQL查询?

这是反序列化实体的脚本的一部分:

    foreach ($serializedEntities as $serializedEntity)
    {
        $detachedEtity = unserialize($serializedEntity);

        $entity = $entityManager->merge($detachedEtity);

        //$entityManager->persist($entity)

    }

    $entityManager->flush();

更新:,我总是会收到这样的错误:

    Notice: Undefined index: 000000002289c17b000000003937ebb0 in /app/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php line 2776

2 个答案:

答案 0 :(得分:0)

您可以使用继承的类定义每个实体的行为,如:

class FieldRepository extends EntityRepository{
   define all specific methods 
}

所以每个实体都将按照课程

的定义进行保存

您还可以使用帮助器概念,这将更快速,更轻松地解决您的问题

OnFlush ---> dispache事件'onFlush' - >在助手类上定义行为

答案 1 :(得分:0)

只是一个辅助类例子

//助手书班
       课程预订{

      public function __construct($container)
    {
        $this->container = $container;
        $this->club_interval = $container->get('X.interval');
        $this->security_context = $container->get('security.context');
                                    // your entity manager 
        $this->em = $container->get('doctrine.orm.entity_manager');
        $this->session = $container->get('session');
        $this->translator = $container->get('translator');
        $this->event_dispatcher = $container->get('event_dispatcher');
        $this->price = 0;
    }

    public function serialize()
    {
        $this->session->set('booking', serialize($this->booking));
    }

    public function unserialize()
    {
        $b = unserialize($this->session->get('booking'));

        $partner = null;
        foreach ($b->getUsers() as $u) {
            $partner = $this->em->getReference('X:User', $u->getId());;
        }

        $field = $this->em->getReference('X:Field', $b->getField()->getId());
        $user = $this->em->getReference('X:User', $b->getUser()->getId());
        $this->buildBooking($field, $b->getFirstDate(), $b->getEndDate(), $user, $partner, $b->getGuest());
    }

///////////////////////////////////////////////      
// here you can choose your database manager check __constructor      
////////////////////////////////////////////
        public function save(){

        $this->em->persist($this->booking);
        $this->em->flush();

        if ($this->booking->getStatus() >= \X\BookingBundle\Entity\Booking::CONFIRMED) {
            $event = new \X\BookingBundle\Event\FilterBookingEvent($this->booking);
            $this->event_dispatcher->dispatch(\X\BookingBundle\Event\Events::onBookingConfirm, $event);
        }

        $this->em->flush();

        return $this->booking;
    }

所以你可以直接从你的Symfony2控制器触发这个类方法,使用save()而不是persist() 或使用事件调度程序,但更棘手

 if (false === $this->get('security.context')->isGranted('ROLE_USER')) {
        throw new AccessDeniedException();
    }

    $b = $this->get('X_helper.booking');
    $b->unserialize();
    $b->setStatus(\X\BookingBundle\Entity\Booking::PENDING);
    /////////////////////////////////////
    // here use helper's method save instead of flush
    $b->save();

    return $this->redirect($this->generateUrl(' route '));