我的问题引用了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();
这样一切都好。 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
答案 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 '));