错误时教条坚持多对一(人对公司)复制公司时保存


Error when doctrine persist many-to-one (people-to-company) duplicate company when saving

我想要什么

我在会话中保存了一个类型为App'Model'Company的对象,在插入新客户时,我需要对已注册的这家公司进行适当的引用。

目前发生

当保存App'Model'People的新记录时,将创建App'Model'Company的新记录(具有会话中相同的数据记录),并且我要创建的Crm'Model'People的新记录与新的App'Model'Company注册有关,而不是与以前的记录有关。

这是我的People实体:

use Doctrine'ORM'Mapping as ORM;
/**
 * @ORM'Entity
 * @ORM'Table(name="tbl_crm_people")
 */
class People extends Entity
{
    /**
     * @ORM'Id
     * @ORM'Column(type="integer");
     * @ORM'GeneratedValue(strategy="AUTO")
     */
    protected $people_id;
    /**
     * @ORM'ManyToOne(targetEntity="App'Model'Company", cascade={"all"})
     * @ORM'JoinColumn(name="people_company_id", referencedColumnName="company_id")
     */
    protected $people_company;
    /**
     * @ORM'Column(type="string", length=60)
     */
    protected $people_name;
}

和我的Company实体

<?php
namespace App'Model;
use Doctrine'ORM'Mapping as ORM;
/**
 * @ORM'Entity
 * @ORM'Table(name="tbl_app_company")
 */
class Company extends Entity
{
    /**
     * @ORM'Id
     * @ORM'Column(type="integer");
     * @ORM'GeneratedValue(strategy="AUTO")
     */
    protected $company_id;
    /**
     * @ORM'Column(type="string", length=250)
     */
    protected $company_name;
    public function getId()
    {
        return $this->company_id;
    }
}

和动作:

public function saveAction()
{
    //INSTANCIA UM FORMULARIO
    $form = new PeopleForm();
    //INFORMAÇÕES SOBRE A REQUISIÇÃO
    $request = $this->getRequest();
    //SE TIVER SIDO UMA REQUIZIÇÃO POST
    if ($request->isPost()) {
        $people = new People;
        $form->setInputFilter($people->getInputFilter());
        $form->setData($request->getPost());
        // CASO O FORMULÁRIO SEJA VÁLIDO
        if ($form->isValid()) {
            // RECEBE DA SESSÃO UM OBETO REFERENTE AO USUÁRIO LOGADO
            $CurrentUser = $this->CurrentUserInfo();
            // ORGANIZA A ESTRUTURA DAS INFORMAÇÕES A SEREM SALVAS
            $data = $form->getData();
            unset($data['submit']);
            // DEFINE O ITEM COM UM OBJETO DO TIPO APP'MODEL'COMPANY
            $data['people_company'] = $CurrentUser->getCompany();
            //CASO SEJA ATUALIZAÇÃO EU SELECIONO O REGISTRO
            if (isset($data['people_id']) && $data['people_id'] > 0) {
                $people = $this->getEntityManager()->find('Crm'Model'People', $data['people_id']);
            }
            // PREENCHO O REGISTRO COM O RESTANTE DOS DADOS
            $people->setData($data);
            // SALVO O REGISTRO
            $this->getEntityManager()->persist($people);
            $this->getEntityManager()->flush();
            return $this->redirect()->toUrl('/crm/people/index');
        }
    }
    //SE FOR VISUALIZAÇÃO DO FORM
    $this->getServiceLocator()->get('ViewHelperManager')->get('HeadTitle')->set('Novo');
    $people_id = (int) $this->params()->fromRoute('id', 0);
    if ($people_id > 0) {
        $this->getServiceLocator()->get('ViewHelperManager')->get('HeadTitle')->set('Edição');
        $people = $this->getEntityManager()->find('Crm'Model'People', $people_id);
        $form->bind($people);
        $form->get('submit')->setAttribute('value', 'Salvar alteração');
    }
    //GERA A VISUALIZAÇÃO
    return new ViewModel(
        array('form' => $form)
    );
}

我会说您应该尝试从您的People实体中删除cascade={"all"}。只有当您想在创建/删除/更新用户的同时创建/删除/更新公司时,才应该添加此选项。我猜这不是你想要的行为。级联操作就是当您发布一个新用户时创建一个新公司的原因。

原则上,如果记录已经存在,则不应该创建新公司。所以我猜你的saveAction也发生了一些不一致的事情。

你确定$CurrentUser->getCompany()返回的是App'Model'Company类型的正确实体吗

创建一个方法来设置People实体中的公司,并使用该方法来设置公司,而不是设置$data['people_company'],这不是更好吗?优点还在于,如果$company不是Company类型,PHP将抛出异常。

public function setCompany(Company $company)
{
    $this->people_company = $company
    return $this;
}