简体   繁体   中英

Doctrine2 Save Many To One Objects

The relation is: MailTemplate may be used by many EMail but EMail is associated only to one MailTemplate .

The problem occurs when trying to insert new records. The error is:

Cannot access empty property

and appears in the setEmail() method

Definition of 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;
    }
}

Definition of EMail :

/**
* @Entity
* @Table(name="EMail")
*/

class EMail
{

    /**
     * @Id
     * @Column(type="integer", options={"unsigned":true})
     * @GeneratedValue(strategy="AUTO")
     */
    protected $emailID;
    // ...
}

Then, I try to create my objects like so:

$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);

I also tried with the __construct() method like so:

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

But I always get the error mentioned above. What am I missing?

Edit (on noobie-php's comment). I've added this to the EMail entity:

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

But still the same error occurs...

Because of the inversedBy="MailTemplate" you have to do in Email entity class :

/**
* @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;
        }
    }

Or simply remove inversedBy in $email property annotation on class MailTemplate

So, finally (as I tought) it was a stupid error.

I had to change the following things:

In the EMail entity:

  • Changed @OneToMany into @ManyToOne .
  • Added inversedBy="EMail"
  • Added cascade={"persist"}

In the MailTemplate entity:

  • Changed @ManyToOne into @OneToMany .
  • Changed inversedBy="MailTemplate" into mappedBy="MailTemplate"

Then one may work with the constructor or a setter to fill data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM