0

I was puzzled by Doctrine\ORM\Mapping issue. I have two entities and they are Many-To-One, Unidirectional releationship. I want to operate Chipinfo(add/update/delete) without impact on producer. Only persist Chipinfo while no persist producer..

class Chipinfo  implements
{
/**
 * @var integer
 *
 * @ORM\Column(name="ChipID", type="integer", nullable=false)
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
protected $chipid;

/**
 * @var \Shop\Entity\Producer
 *
 * @ORM\ManyToOne(targetEntity="Shop\Entity\Producer")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="pId", referencedColumnName="producerid")
 * })
 */
protected $pid;
}  
class Producer{

/**
* @ORM\Id
* @ORM\Column(name="producerid", type="integer");
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $producerId;

/**
* @ORM\Column(name="producername", type="string")
*/
protected $producerName;
}

ChipInfo and Producer are Many-To-One unidirection relationship: A chipinfo can only be built by one producer while one producer can build multiple chipinfos. What I want is that: add/update/removal of items in Chipinfo would not do any impact on Producer.

$chip = new Chipinfo();
$formData = $this->initFormData($form->getData());
$chip->populate($formData);
$this->getEntityManager()->persist($chip);
$this->getEntityManager()->flush();

private function initFormData(&$raw){

    $raw['eid'] = new Encapuser($this->findEntity("Shop\Entity\Encapuser", $raw['eid']));
    $this->log($raw->eid);
    $raw['vid'] = new Vendors($this->findEntity("Shop\Entity\Vendors", $raw['vid']));

    $raw['pid'] = new Producer($this->findEntity("Shop\Entity\Producer", $raw['pid']));

    $this->log($raw);
    return $raw;

}

would throws errors:

    A new entity was found through the relationship 'Shop\Entity\Chipinfo#pid' that was not configured to cascade persist operations for entity: Shop\Entity\Producer@00000000349002ee00000000c955fd11. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist  this association in the mapping for example @ManyToOne(..,cascade={"persist"}). If you cannot find out which entity causes the problem implement 'Shop\Entity\Producer#__toString()' to get a clue.

Then I configured the pid as:

 @ORM\ManyToOne(targetEntity="Shop\Entity\Producer", cascade={"persist"})

Though the error disappear, but this is not what I want. Because when i call flush() for chipinfo with existing producer A, a new A which is duplicated is inserted.

Therefore, my questions are: 1) How should i configure @manyToone field, I did not get clue from http://doctrine-orm.readthedocs.org/en/2.0.x/reference/working-with-associations.html#transitive-persistence-cascade-operations

2) Should I add: @ORM\OneToMany, targetEntity="Shop\Entity\Producer" private @chip;

in producer? If so, would operations(add/delete/update) on producer require construct a @chip?

shijie xu
  • 1,975
  • 21
  • 52
  • Please show your code where you actually try to persist the ChipInfo entity. How do you get the Producer entity that you attach to the ChipInfo object? Is the Producer entity already managed (i.e. retrieved from the entitymanager)? – Ruben Aug 30 '13 at 06:36

1 Answers1

1

You have to set the existing producer (the entity retrieved by doctrine) in the $pid field of your entity.

Why do you create a new Producer ? What does findEntity do ? It does not seem to retrieve the actual entity from Doctrine, why is that ?

Usually what you would do is this :

$chip->setPid($this->getEntityManager()->getRepository('Shop\Entity\Producer')->find($pid));
jchampion
  • 381
  • 1
  • 3