Reputation: 664
Got to handle an entity, called Collection
, which has an array to be saved as a different entity.
This is what I use in the controller, to test my entities:
// setup items in a controller
$i1 = new Item();
$i1->setInfo('test2');
$i2 = new Item();
$i2->setInfo('example');
// create the collection
$pc = new Collection();
$pc->setId(1);
// set some vars / members
$pc->setInfo('test123');
$pc->setOwner(1);
$pc->setGroup(1);
$pc->setConfig(1);
// add the items
$pc->add($pi1);
$pc->add($pi2);
// store everything
$em = $this->getEntityManager();
$em->persist($pc);
$em->flush();
This is my Item
entity:
<?php
/**
* Item
* @package application\Entity
*
* @ORM\Entity
* @ORM\Table(name="items")
*/
class Item
{
/**
* @var int
*
* @ORM\Id
* @ORM\Column(name="id", type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var string
* @ORM\Column(name="info", type="text")
*/
protected $info;
/**
* @var
* @ORM\ManyToOne(targetEntity="Collection", inversedBy="items")
* @ORM\JoinColumn(name="cid", referencedColumnName="id")
*/
protected $collection;
protected $collection;
/**
* @return string
*/
public function getInfo()
{
return $this->info;
}
/**
* @param string $info
*/
public function setInfo($info)
{
$this->info = $info;
}
}
This is the code in the collection entity
/**
* Collection
* @package Application\Entity
*
* @ORM\Entity
* @ORM\Table(name="collections")
*/
class Collection
{
/**
* @var int
*
* @ORM\Id
* @ORM\Column(name="id", type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var string
*
* @ORM\Column(name="usr", type="integer")
*/
protected $owner;
/**
* @var string
*
* @ORM\Column(name="grp", type="integer")
*/
protected $group;
/**
* @var string
*
* @ORM\Column(name="cnf", type="integer")
*/
protected $config;
/**
* @var string
*
* @ORM\Column(name="info", type="text")
*/
protected $info;
/**
* @var
* @ORM\OneToMany(targetEntity="Item", mappedBy="items", cascade="all")
*/
protected $items;
public function __construct(){
$this->items = new ArrayCollection();
}
public function add(Item $oItem){
$this->items->add($oItem);
}
I would expect it to create items which have the id
of the Collection
in their column 'cid'. But this column is always null
:
And another problem, it always saves a new Collection
. I expected that setting the id
would override the original.
Upvotes: 2
Views: 51
Reputation: 10099
I strongly recommend reading several times to fully understand the differences between owning-side and inverse-side before playing with bi-directional associations.
The Item
entity is owning-side in this scenario (from doctrine's perspective) (1). You're persisting the inverse-side (2). Doctrine will only check the owning side of an association for changes (3). Also some setters & getters are missing in your entities which required to build a correct bidirectional relationship (4).
Add this methods to Item
entity:
public function setCollection(Collection $col = null)
{
$this->collection = $col;
return $this;
}
public function getCollection()
{
return $this->collection;
}
And change the add
method in Collection
entity something like this:
public function add(Item $oItem)
{
$this->items->add($oItem);
$oItem->setCollection($this); // Notice this line
}
When you want to remove an Item
from a Collection
;
public function removeItem(Item $oItem)
{
$this->items->removeElement($oItem);
$oItem->setCollection(null); // This is important too
}
You may also want to read about transitive persistence section of the documentation before using cascade="all"
strategy.
Hope it helps.
Upvotes: 2