原则二:保存多对一对象


Doctrine2 Save Many To One Objects

关系是:MailTemplate可以被多个EMail使用,但是EMail只关联一个MailTemplate

尝试插入新记录时出现问题。错误是:

不能访问空属性

,出现在setEmail()方法

MailTemplate的定义:
/**
* @Entity
* @Table(name="MailTemplate")
*/
class MailTemplate
{
    /**
     * @Id
     * @Column(type="integer", options={"unsigned":true})
     * @GeneratedValue(strategy="AUTO")
     */
    protected $mailtemplateID;
    /**
     * @ManyToOne(targetEntity="EMail", inversedBy="MailTemplate")
     * @JoinColumn(name="emailID", referencedColumnName="emailID")
     **/
    protected $email = null;
    // ...
    public function setEmail(EMail $email)
    {
        $this->$email = $email;
    }
}
EMail的定义:
/**
* @Entity
* @Table(name="EMail")
*/
class EMail
{
    /**
     * @Id
     * @Column(type="integer", options={"unsigned":true})
     * @GeneratedValue(strategy="AUTO")
     */
    protected $emailID;
    // ...
}

然后,我试着像这样创建我的对象:

$mail_template = new MailTemplate();
$email = new EMail();
//... Adding values with the usual setter methods
$entity_manager->persist($email);
$entity_manager->flush($email);
$mail_template->setEmail($email);
$entity_manager->persist($mail_template);
$entity_manager->flush($mail_template);

我还尝试了__construct()方法,如下所示:

// Inside the MailTemplate class
public function __construct(EMail $email)
{
    $this->$email = $email;
}

但我总是得到上述错误。我错过了什么?

编辑(对noobie-php的注释)。我已将此添加到EMail实体:

/**
 * @Id
 * @Column(type="integer", options={"unsigned":true})
 * @GeneratedValue(strategy="AUTO")
 * @OneToMany(targetEntity="MailTemplate", mappedBy="EMail")
 * @JoinColumn(name="mailtemplateID", referencedColumnName="mailtemplateID")
 */
protected $emailID;

因为inversedBy="MailTemplate"你必须在Email实体类中做:

/**
* @Entity
* @Table(name="EMail")
*/
use Doctrine'Common'Collections'ArrayCollection;
class EMail
{
    /**
     * @Id
     * @Column(type="integer", options={"unsigned":true})
     * @GeneratedValue(strategy="AUTO")
     */
    protected $emailID;
   /**
     * @OneToMany(targetEntity="EMailTemplate", mappedBy="email")
     **/
    protected $mailTemplates = [];
    public function __construct()
    {
        parent::__construct();
        $this->mailTemplates = new ArrayCollection();
    }
    // getter and setters

MailTemplate.php

/**
 * @Entity
 * @Table(name="MailTemplate")
 */
 class MailTemplate
 {
        /**
         * @Id
         * @Column(type="integer", options={"unsigned":true})
         * @GeneratedValue(strategy="AUTO")
         */
        protected $mailtemplateID;
        /**
         * @ManyToOne(targetEntity="EMail")
         * @JoinColumn(name="emailID", referencedColumnName="emailID", nullable=true)
         **/
        protected $email = null;
        // ...
        public function setEmail(EMail $email)
        {
            $this->$email = $email;
        }
    }

或者直接删除MailTemplate类的$email属性注释中的inversedBy

所以,最后(我认为)这是一个愚蠢的错误。

我必须更改以下内容:

EMail实体:

  • @OneToMany变为@ManyToOne
  • 新增inversedBy="EMail"
  • 新增cascade={"persist"}

MailTemplate实体中:

  • @ManyToOne更改为@OneToMany
  • inversedBy="MailTemplate"更改为mappedBy="MailTemplate"

然后可以使用构造函数或setter来填充数据。