根据Doctrine 2.0文档(http://docs.doctrine-project.org/en/2.0.x/reference/working-with-objects.html)a
..预先存在的托管实体,被persist操作忽略。但是,如果从X到这些其他实体的关系用cascade = PERSIST或cascade = ALL映射(请参阅“传递持久性”),则持久化操作会级联到X引用的实体。“
我的理解是,级联到引用的托管实体应该导致被引用的实体被persist操作忽略(案例3):
可达性持久性:级联持续
- 标记为级联持久化的集合中的新实体将由Doctrine直接保留。
- 未标记为级联持久化的集合中的新实体将产生异常并回滚flush()操作。
- 将跳过没有新实体的集合。
醇>
但事实并非如此。我有一个托管Channel
实体,其中包含1:n Properties
和Data
个实体。创建Channel
实体时,会检索一些属性但不会修改。
当我添加数据并通过
持久保存实体时$channel->addData(new Model\Data($channel, $timestamp, $value));
$em->persist();
我可以看到用于编写新Data
实体的SQL,但也看到现有Properties
的更新(使用旧的,未更改的值)。
为什么Doctrine(2.4.1)会保持托管实体的关系?
实体定义如下所示:
class Channel extends Entity {
/**
* @OneToMany(targetEntity="Data", mappedBy="channel", cascade={"persist"}, orphanRemoval=true)
* @OrderBy({"timestamp" = "ASC"})
*/
protected $data = NULL;
/**
* Constructor
*/
public function __construct($type) {
parent::__construct($type);
$this->data = new ArrayCollection();
}
/**
* Add a new data to the database
*/
public function addData(\Volkszaehler\Model\Data $data) {
$this->data->add($data);
}
...
}
abstract class Entity {
/**
* @OneToMany(targetEntity="Property", mappedBy="entity", cascade={"remove", "persist"}, orphanRemoval=true)
* @OrderBy({"key" = "ASC"})
*/
protected $properties = NULL;
/**
* Constructor
*
* @param string $type
*/
public function __construct($type) {
if (!Definition\EntityDefinition::exists($type)) {
throw new \Exception('Unknown entity type: \'' . $type . '\'');
}
$this->properties = new Collections\ArrayCollection();
}
...
}
答案 0 :(得分:1)
我终于断言,Doctrine 不坚持持久引用被管理实体。
在上面描述的情况下,我修改了相关实体(在某些属性上更改了类型),由于在计算更改集时进行===
比较,Doctrine确实将其解释为更新。
有一些关于使用PostFlush
事件来阻止这种情况的讨论,但是没有结论:https://github.com/doctrine/doctrine2/pull/382#issuecomment-43421295