原则级联选项为一个多



我很难理解Doctrine手册对级联操作的解释,需要有人帮助我理解简单的多对一关系方面的选项。

在我的应用程序中,我有一个名为Article的表/实体,它有一个外键字段,引用名为Topic的表/实体中的'id'字段。

当我创建一个新文章时,我从下拉菜单中选择主题。在Article表的'topic_id'外键字段中插入一个整数。

我在Article实体中设置了$topic关联,如下所示:

/**
 * @ManyToOne(targetEntity="Topic")
 * @JoinColumn(name="topic_id", referencedColumnName="id", nullable=false)
 */
private $topic;

Topic实体没有任何关于Article实体的往复注释。主题不关心什么文章引用了它们,当引用主题的文章被删除时,主题不需要发生任何事情。

因为我没有在Article实体中指定级联操作,所以当我尝试创建一个新的Article时,Doctrine抛出一个错误:"通过未配置为级联持久操作的关系找到了一个新实体。显式持久化新实体或在关系上配置级联持久化操作。"

所以我知道我需要选择一个级联操作来包含在Article实体中,但是我如何知道在这种情况下选择哪个操作呢?

从教条手册来看,"分离"听起来是正确的选择。但是在这里和这里研究其他人类似的问题,让我觉得我应该用"坚持"来代替。

谁能帮我理解"持久"、"删除"、"合并"one_answers"分离"在我所描述的简单的多到一关系中是什么意思?

在Doctrine2文档"9.6。传递持久化/级联操作:这里有几个例子说明如何配置实体,以便在持久化$article时,也持久化$topic。在您的情况下,我建议为Topic实体添加以下注释:

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

这个解决方案的缺点是你必须把$articles集合包含到Topic实体中,但是你可以把它保留为私有,不需要getter/setter。

和@kurt-krueckeberg提到的,你必须传递真正的主题实体时,创建新的文章,即:

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

祝你好运!

如果你有一个@OneToMany单向关联,就像在Doctrine Reference的6.10节中描述的那样,那么很可能你在调用flush之前忘记了持久化Topic。不要在Article中设置topic_id主键。而是设置Topic实例。

例如,给定如下的Article和Topic实体:

<?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;}
}

生成模式后:

# doctrine orm:schema-tool:create

保存这些实体的代码应该是这样的

//configuration omitted..
$em = DoctrineORMEntityManager::create($connectionOptions, $config);
$topic = new EntitiesTopic();
$article1 = new EntitiesArticle("article 1");
$article2 = new EntitiesArticle("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;

我希望这对你有帮助。

相关内容

最新更新