我很难理解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;
我希望这对你有帮助。