Doctrine Cascade Options for OneToMany

后端 未结 2 869
粉色の甜心
粉色の甜心 2020-12-24 05:21

I\'m having a hard time making sense of the Doctrine manual\'s explanation of cascade operations and need someone to help me understand the options in terms of a simple Many

相关标签:
2条回答
  • 2020-12-24 05:55

    In the Doctrine2 documentation "9.6. Transitive persistence / Cascade Operations" there are few examples of how you should configure your entities so that when you persist $article, the $topic would be also persisted. In your case I'd suggest this annotation for Topic entity:

    /**
     * @OneToMany(targetEntity="Article", mappedBy="topic", cascade={"persist", "remove"})
     */
     private $articles;  
    

    The drawback of this solution is that you have to include $articles collection to Topic entity, but you can leave it private without getter/setter.

    And as @kurt-krueckeberg mentioned, you must pass the real Topic entity when creating new Article, i.e.:

    $topic = $em->getRepository('Entity\Topic')->find($id);
    $article = new Article($topic);
    $em->persist($article);
    $em->flush();
    
    // perhaps, in this case you don't even need to configure cascade operations
    

    Good luck!

    0 讨论(0)
  • 2020-12-24 06:06

    If you have a @OneToMany unidirectional association, like that described in section 6.10 of the Doctrine Reference, then most likely you forgot to persist the Topic before calling flush. Don't set the topic_id primary key in Article. Instead set the Topic instance.

    For example, given Article and Topic entities like these:

    <?php
    namespace Entities;
    
    /**
    @Entity
    @Table(name="articles")
    */
    class Article {
    
    /**
    *  @Id
    *  @Column(type="integer", name="article_id") 
    *  @GeneratedValue
    */
        protected $id;  
    
    /**
    *  @Column(type="text") 
    */
     protected $text;
    
    /** 
    * @ManyToOne(targetEntity="Topic", inversedBy="articles")
    * @JoinColumn(name="topic_id", referencedColumnName="topic_id")
    */ 
     protected $topic; 
    
     public function __construct($text=null)
     {
        if (!is_null($text)) {
             $this->text = $text;
        }
     }
     public function setArticle($text)
     {
         $this->text = $text;
     }
    
     public function setTopic(Topic $t)
    {
         $this->topic = $t;
    }
    } 
    
    <?php
    namespace Entities;
    /**
      @Entity
      @Table(name="topics")
    */
    class Topic {
    
    /**
    *  @Id
    *  @Column(type="integer", name="topic_id") 
    *  @GeneratedValue
    */
        protected $id;  
    
        public function __construct() {}
    
        public function getId() {return $this->id;}
    }
    

    After you generate the schema:

    # doctrine orm:schema-tool:create
    

    your code to persist these entities would look like something this

    //configuration omitted..
    $em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);
    
    $topic = new Entities\Topic();
    $article1 = new Entities\Article("article 1");
    $article2 = new Entities\Article("article 2");
    $article1->setTopic($topic);
    $article2->setTopic($topic);
    $em->persist($article1);
    $em->persist($article2);
    $em->persist($topic);
    
    try {
        $em->flush();
    } catch(Exception $e) {
        $msg= $e->getMessage();
        echo $msg . "<br />\n";
    }
    return;
    

    I hope this helps.

    0 讨论(0)
提交回复
热议问题