Эта проблема кажется уникальной, если: 1) вы используете таблицу объединений с составными ключами, 2) формируете компонент, а 3) таблица соединений - это сущность, которая строится в поле «коллекция» компонента формы. Я видел много людей, имеющих проблемы, но не так много решений, поэтому я думал, что поделюсь с вами.
Я хотел сохранить свой составной первичный ключ, поскольку я хотел убедиться, что в базе данных будет сохраняться только один экземпляр двух внешних ключей.Использование 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
объект в форме, которая имела поле коллекция OrderItem
с, я не смог бы сохранить OrderItem объект без сначала сохранили объект Order Entity (так как доктрина/SQL нуждается в идентификаторе заказа для составного ключа), но Doctrine EntityManager не позволял мне сохранять объект Order, у которого есть атрибуты 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;
}
....
}
И тогда в моем контроллере, где я обрабатывать форму для заказа.
//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). Но это доктрина для вас, со всей ее силой, она обязательно может поставить вас в привязку. Но, к счастью, вам придется делать это только при создании нового объекта, а не редактировании, потому что объект уже находится в базе данных.
Вы правы, я пытаюсь добавить заказ и отношение для контакта в одно и то же время. Я попытался очистить порядок раньше, но затем я получаю сообщение об ошибке 'cascade = {" persist "}', и если я верну его, он попытается сначала сохранить отношение. У вас есть рабочий пример? Я не могу найти один ... – cheesemacfly
вам нужно вручную сохранить отношения. Все 'cascade = {" persist "}' есть, если вы сохраняете сущность с отношением с этим набором, она автоматически добавит '$ em-> persist ($ relationshipObject)' Итак, чтобы исправить вашу проблему, вам нужно будет оставить это выключить и вручную сохранить объекты отношений и сделать второй сброс. –
Но если я попытаюсь удалить 'cascade = {" persist "}', а затем сначала перенести/очистить объект заказа, я получаю a: 'Новый объект был найден через отношение TEST \ MyBundle \ Entity \ Orders # relations ' который не был настроен на каскадное сохранение операций для объекта: TEST \ MyBundle \ Entity \ Relations ... '. Я даже пытался использовать 'detach()' на объекте отношений, но без успеха ... – cheesemacfly