这是一个多对多关联,但在连接表上有一个属性,所以I have to use One-To-Many/Many-To-One associations.
我有一个表单,我可以在一个订单项目中添加尽可能多的关系并同时创建它(主要受文档中的How to Embed a Collection of Forms教程的启发.
当我发布表单时,我收到以下错误:
Entity of type TEST\MyBundle\Entity\Relation has IDentity through
a foreign entity TEST\MyBundle\Entity\Order,however this entity
has no IDentity itself. You have to call EntityManager#persist() on
the related entity and make sure that an IDentifIEr was generated
before trying to persist ‘TEST\MyBundle\Entity\Relation’. In case
of Post Insert ID Generation (such as MysqL auto-Increment or
Postgresql SERIAL) this means you have to call EntityManager#flush()
between both persist operations.
我理解这个错误,因为Doctrine试图保持与订单相关的Relation对象,因为我在OnetoMany关系上有cascade = {“persist”}选项.但是我怎么能避免这种行为呢?
我试图删除cascade = {“persist”}并手动保持实体,但我得到相同的错误(因为我需要flush()命令来获取ID,当我这样做时,我有相同的错误消息) .
我还尝试在flush()之前分离()Relation对象,但没有运气.
我想保留我的复合主键,因为我想确保两个外键中只有一个实例会在数据库中保留.运用
以this entity setup为例
/** @Entity */class Order{ /** @OnetoMany(targetEntity="OrderItem",mappedBy="order") */ private $items; public function __construct(Customer $customer) { $this->items = new Doctrine\Common\Collections\ArrayCollection(); }}/** @Entity */class Product{ /** @OnetoMany(targetEntity="OrderItem",mappedBy="product") */ private $orders; ..... public function __construct(Customer $customer) { $this->orders = new Doctrine\Common\Collections\ArrayCollection(); }}/** @Entity */class OrderItem{ /** @ID @ManyToOne(targetEntity="Order") */ private $order; /** @ID @ManyToOne(targetEntity="Product") */ private $product; /** @Column(type="integer") */ private $amount = 1;}
我面临的问题是,如果我在表单中构建一个Order对象,它有一个OrderItems的集合字段,我将无法在没有首先保存订单实体的情况下保存OrderItem实体(因为doctrine / sql需要订单)复合键的ID),但Doctrine EntityManager不允许我保存具有OrderItem属性的Order对象(因为它坚持将它们保存在一起).您无法关闭级联,因为它会先抱怨您尚未保存关联的实体,并且在保存订单之前无法保存关联的实体.真是个难题.我的解决方案是删除关联的实体,保存Order,然后将关联的实体重新引入Order对象并再次保存.所以首先我创建了一个ArrayCollection属性$items的质量赋值函数
class Order{ ..... public function setItemsArray(Doctrine\Common\Collections\ArrayCollection $itemsArray = null){ if(null){ $this->items->clear(); }else{ $this->items = $itemsArray; } ....}
然后在我的Controller中处理Order的表单.
//get entity manager$em = $this->getDoctrine()->getManager();//get order information (with items)$order = $form->getData();//pull out items array from order$items = $order->getItems();//clear the items from the order$order->setItemsArray(null);//persist and flush the Order object$em->persist($order);$em->flush();//reintroduce the order items to the order object$order->setItemsArray($items);//persist and flush the Order object again ):$em->persist($order);$em->flush();
它很糟糕,你必须坚持和冲洗两次(见更多这里Persist object with two foreign identities in doctrine).但这对你来说是主义,它具有所有的力量,它肯定可以让你陷入困境.但幸运的是,您只需在创建新对象而不是编辑时执行此 *** 作,因为该对象已在数据库中.
总结以上是内存溢出为你收集整理的symfony – 复合键和表单全部内容,希望文章能够帮你解决symfony – 复合键和表单所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)