我正在使用Symfony2和条令
我有一个条令实体,它被序列化/未序列化为一个会话,并在多个屏幕中使用。该实体具有多个一对多关联。
条令实体有以下一对多,例如:
class Article {
...
/**
* @ORMOneToMany(targetEntity="image", mappedBy="article", cascade= {"merge","detach","persist"})
*/
protected $images;
public function __construct()
{
$this->images = new ArrayCollection();
}
.....
}
物品实体的保存和检索如下:
public function saveArticle($article)
{
$articleSerialized = serialize($article);
$this->session->set('currentArticle',$articleSerialized);
}
public function getArticle()
{
$articleSerialized = $this->session->get('currentArticle');
$article = unserialize($articleSerialized);
$article = $this->em->merge($article);
return $article;
}
我可以多次保存实体并将其加载到会话中,然后将其合并回实体管理器并保存。只有当它是一个新实体时,才会出现这种情况。
然而,一旦我从数据库加载了一个实体,然后将其保存到会话中,我就会遇到问题。
我从其他帖子中知道,在你取消对一个保存的实体的序列化后,你必须运行$em->merge($entity);
我可以合并实体,添加新的子实体(一对多),然后保存:
$article = $this->getArticle(); //Declared above, gets article from session
$image = new Image();
$image->setFilename('image.jpeg');
$article->addImage($image);
$this->saveArticle($article); //Declared above, returns the article to session
但是,在第一次合并和图像添加之后,我无法再添加任何子实体。如果我尝试添加第二个图像,它会返回以下错误:
A managed+dirty entity <<namespace of entity>>
image@0000000067078d7400000000221d7e02 can not
be scheduled for insertion.
总之,我可以对实体进行任意数量的更改,并将其保存到会话中,但如果在添加子实体时多次运行$em->merge,则新的子实体将被标记为脏实体。
有人知道为什么一个实体会被标记为肮脏吗?我需要重置实体本身吗?如果需要,我该怎么做?
明白了。
对于任何可能在未来遇到这个问题的人:
不能合并具有未受限制的子实体的实体。它们被标记为肮脏。
I.E
您可能有一篇文章,其中有两个图像已经保存到数据库中。
ARTICLE (ID 1) -> IMAGE (ID 1)
-> IMAGE (ID 2)
如果你将文章序列化保存到会话中,然后取消序列化并合并它。这没关系。
若您添加了一个新的映像,然后将其序列化到会话,那个么您将遇到问题。这是因为您无法合并未受约束的实体。
ARTICLE (ID 1) -> IMAGE (ID 1)
-> IMAGE (ID 2)
-> IMAGE (NOT YET PERSISTED)
我要做的是:
在我取消文章的序列化后,我删除了未受干扰的图像,并将它们存储在一个临时数组中(我检查ID)。然后我合并了文章并重新添加了未被阻止的图片。
$article = unserialize($this->session->get('currentArticle'));
$tempImageList = array();
foreach($article->getImages() as $image)
{
if(!$image->getId()) //If image is new, move it to a temporary array
{
$tempImageList[] = $image;
$article->removeImage($image);
}
}
$plug = $this->em->merge($article); //It is now safe to merge the entity
foreach($tempImageList as $image)
{
$article->addImage($image); //Add the image back into the newly merged plug
}
return $article;
如果需要的话,我可以添加更多的图像,并重复这个过程,直到我最终将文章保存回DB。
在需要进行多页创建过程或通过AJAX添加图像的情况下,这一点很方便。