【问题标题】:Detach and serialize doctrine entities分离和序列化学说实体
【发布时间】:2013-10-11 17:42:55
【问题描述】:

我的问题参考Doctrine many-to-many relations and onFlush event

作者实体: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();

这样就一切OK了。 Doctrine 生成三个查询:create author、create book 和 create links at author_books。

但我需要在 onFlush 事件中分离和序列化所有实体,并将它们保存在 NoSQL 数据库中。然后其他脚本将反序列化所有这些实体并将它们保存到数据库中。并且通过这种方式,Doctrine 只生成了两个 SQL 查询:create book 和 create author。我应该怎么做教义也生成链接表的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

【问题讨论】:

  • 哇,这似乎是个非常糟糕的主意。你为什么不实现一个更高级别的服务,由学说 orm 和 nosql/queue 组成,而不是黑客学说?
  • 此服务可以实现 ObjectManager 或扩展 ObjectManagerDecorator(如果您愿意)。此服务将推迟持久调用(如果需要,可以通过序列化)。
  • 但坦率地说,我不明白你的目标?
  • 我不破解教义。序列化和反序列化中的任何问题。有什么方法可以在执行之前获取所有生成的 SQL 查询?
  • 是的,我知道您不会“破解”学说,但您使用松散耦合的事件驱动流,几乎不需要耦合行为。

标签: php symfony serialization doctrine-orm entities


【解决方案1】:

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

class FieldRepository extends EntityRepository{
   define all specific methods 
}

所以每个实体都将按照类中的定义保存

您也可以使用助手概念,这将更快更轻松地解决您的问题

OnFlush ---> 调度事件 'onFlush' --> 定义辅助类的行为

【讨论】:

  • 我知道存储库,但请您说得更清楚些。看来我不明白你:(
【解决方案2】:

只是一个帮助类的例子

// 助手书类
课程预订{

      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 '));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多