如何创建一个实体集合的克隆而不教条preserving关系? [英] How to create a clone of an entity collection without preserving relationship in doctrine?

查看:189
本文介绍了如何创建一个实体集合的克隆而不教条preserving关系?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在试图找出如何得到这个沿时间,但没有任何的运气工作。由于复杂的逻辑,在一个应用程序,我的工作,我需要创建一个孤立的克隆一个实体集合没有 preserving什么那么关系到数据库。无论改变我做的克隆集合不应由学说在所有跟踪,应视为不存在。

I've been trying to figure out how to get this to work for along time but without any luck. Due to a complex logic in an app I'm working on, I need to create an isolated clone of a entity collection without preserving what so ever relation to the database. Whatever changes I do on the cloned collection should not be tracked by Doctrine at all and should be treated as if it doesn't exist at all.

下面是一个例子code:

Here's an example code:

 /* 
  * @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;

}

我已经试过以下code在我的控制器集合存储到会话中,但它仍然以某种方式存储的关系:

I've already tried the following code in my controller to store the collection into the session but it still somehow stores the relationships:

 $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);


显然,我在这里做得不对,因为我最终不得不在收集更多的结果时,刷新荷兰国际集团即使集合本身具有正确的记录数目的实体。我有一个怀疑,在某个地方链主义不能正确计算有什么需要做的事情。


Apparently I'm doing something wrong here because I end up having more results in the Car collection when flushing the entity even though the collection itself has the correct number of records. I have a suspicion that somewhere in the chain Doctrine doesn't compute correctly what needs to be done.

如何解决或调试任何想法或方向?

Any ideas or directions on how to solve or debug this?

追问的问题:当从会话中检索后面的克隆集合将它仍然是一个孤立的克隆或学说将尝试把它合并?

Follow-up question: When retrieving back the cloned collection from the session will it still be an isolated clone or Doctrine will try merge it back?

推荐答案

我在写这个答案作出指示任何人谁可能有类似的问题。我无法找到很多话题或文件以这种方式这就是为什么我决定分享我的经验。我对教义没有深刻专家的它在内部如何工作的,所以我不会进入它是如何工作的大细节。我宁愿把重点放在最终的结果。

I'm writing this answer to give directions to anybody who might have similar issues. I couldn't find many topics or documentation in this manner which is why I decided to share my experience. I am no deep expert on Doctrine an how it internally works, so I won't go into big details of "how it works". I will rather focus on the end result.

存储其有关系的其他实体为一个会话实体是很成问题。当您从会话检索,学说失去跟踪的关系(一对多,多对一等)。这导致一些不良后果:

Storing entities which have relations to other entities into a session is quite problematic. When you retrieve it from the session, Doctrine loses track of the relationships (OneToMany, ManyToOne, etc). This leads to some undesired effects:

  1. 主义错误地决定插入现有实体的一个新纪录。
  2. 主义可能会引发异常,如一个新的实体是通过关系尖端\ MyBundle \实体\人#车',这不是配置级联坚持实体操作发现:欧宝。为了解决这个问题:要么显式调用EntityManager的#坚持()对这个未知的实体或配置级联坚持这个协会在映射例如@ManyToOne(..,级联= {坚持})。和至少2个其它类型的异常可能看起来完全不相干在第一。
  1. Doctrine wrongly decides to insert a new record of an existing entity.
  2. Doctrine might throw exceptions such as A new entity was found through the relationship 'Acme\MyBundle\Entity\Person#cars' that was not configured to cascade persist operations for entity: Opel. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"}). and at least 2 other types of exceptions which might seem totally irrelevant at first.

显然,从数据库中获取的结果,其原样当你的会话事情变得很凌乱,特别是如果实体有关系的其他实体(这是我的情况)。付大的关注,如果你有实体关系 - 他们可能需要刷新如果你开始变得怪异异常

Apparently when fetching a result from the database and it "as-is" in your session things get really messy, specially if the entity has relations to other entities (which was my case). Pay big attention if you have entity relationships - they might need to be "refreshed" if you start getting strange exceptions.

有几种方法来解决这个问题。其中之一是使用使用通过形式发送(如@flec建议)数据 $ myForm->的getData()。这种方法可能很好地帮助你,但遗憾的是它不符合我的情况下(太复杂,解释)。

There are a couple of ways to overcome this issue. One of which is to use the data sent via the form (as @flec suggested) by using $myForm->getData(). This approach might work well for you, but unfortunately it was not the case with me (too complex to explain).

我最终什么做什么是在实体实施 \序列化。我还创建()名为 __的toArray方法,该方法将我的实体到一个数组。您在 __的toArray()方法返回哪些数据是完全取决于你和你的业务逻辑。该阵列的数据存储到会话,并且用它来重新创建了所有必要的关系,一个新的对象。

What I ended up doing was implementing the \Serializable in the entity. I also created a method called __toArray() which converted my entity into an array. What data you return in the __toArray() method is totally up to you and your business logic. The array data is stored into the session and you use it to re-create a fresh object with all necessary relations.

希望这可以帮助别人。

这篇关于如何创建一个实体集合的克隆而不教条preserving关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆