【发布时间】:2015-08-13 17:48:04
【问题描述】:
我一直试图弄清楚如何让它工作很长时间,但没有任何运气。由于我正在处理的应用程序中的复杂逻辑,我需要创建一个实体集合的隔离clone,而不保留与数据库的任何关系。 Doctrine 根本不应该跟踪我对克隆集合所做的任何更改,并且应该将其视为根本不存在。
这是一个示例代码:
/*
* @ORM\Entity()
*/
class Person
{
/**
* @var integer
*
* @ORM\Id
* @ORM\Column(name="person_id", type="integer",nullable=false)
* @ORM\GeneratedValue(strategy="AUTO")
*/
public $id;
/**
* @var ArrayCollection
*
* @ORM\OneToMany(targetEntity="Car", mappedBy="person", cascade={"persist"})
*/
public $cars;
}
/**
* @ORM\Entity()
* @ORM\HasLifecycleCallbacks()
*/
class Car
{
/**
* @var integer
*
* @ORM\Id
* @ORM\Column(name="car_id", type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/*
* @ORM\JoinColumn(name="person_id", referencedColumnName="person_id", nullable=true)
* @ORM\ManyToOne(targetEntity="Person", inversedBy="cars", cascade={"persist"})
*/
private $person;
}
我已经尝试在我的控制器中使用以下代码将集合存储到会话中,但它仍然以某种方式存储了关系:
$tmp = clone $person;
$this->get('session')->set('carCollection', $tmp->getCars());
$tmpCars = clone $person->getCars();
$tmpCollection = new ArrayCollection();
foreach($tmpCars as $car) {
$tmpCollection->add(clone $car);
}
$this->get('session')->set('carCollection', $tmpCollection);
$tmpCars = clone $person->getCars();
$tmpCollection = new ArrayCollection();
foreach($tmpCars as $car) {
$clone = clone $car;
$entityManager->detach($car);
$tmpCollection->add(clone $clone);
}
$this->get('session')->set('carCollection', $tmpCollection);
显然我在这里做错了,因为当flushing 实体时,我最终在Car 集合中得到更多结果,即使集合本身具有正确数量的记录。我怀疑链 Doctrine 中的某个地方没有正确计算需要做什么。
关于如何解决或调试此问题的任何想法或指示?
后续问题:从会话中检索克隆的集合时,它仍然是一个孤立的克隆,还是 Doctrine 会尝试将其合并回来?
【问题讨论】:
-
感谢您的评论!我已经尝试过了,但问题仍然存在。我真正想做的是在会话中拥有一个集合的副本,修改它(在会话中)。当用户提交实际表单时,来自会话的集合会通过一个业务逻辑,该业务逻辑决定将哪些内容放入实际集合中。再次 - 这个业务逻辑工作正常,因为当我在坚持
$person之前执行$person->getCars()->count()时,它会返回正确数量的实体和正确的数据。 -
我也一直在会话中存储实体,我不会推荐它。它很容易出错。问题是您必须使用
merge方法合并主实体。之后,您必须刷新关系。这意味着您必须创建一个临时集合(就像您所做的那样)从现有实体中获取 id 并使用getReference方法添加引用。我建议改为存储表单数据。 -
你能给我举个例子吗?我相信您说的是直接将
$myForm->getData()存储到会话中,然后直接从会话中使用它?对吗? -
是的,我认为这可能是一个好方法。不幸的是,我对 symfony2 不熟悉,但我认为您可以将存储的表单数据绑定到另一个请求中的表单。然后使用表单更新您的实体。
标签: ajax symfony session serialization doctrine-orm