我正在使用Doctrine ODM并尝试制作自定义映射类型,但我遇到了一些问题。 我的映射类型与集合类型类似,但它适用于ArrayCollection:
<?php
class ArrayCollectionType extends Type
{
public function convertToDatabaseValue($value)
{
return $value !== null ? array_values($value->toArray()) : null;
}
public function convertToPHPValue($value)
{
return $value !== null ? new ArrayCollection($value) : null;
}
public function closureToMongo()
{
return '$return = $value !== null ? array_values($value->toArray()) : null;';
}
public function closureToPHP()
{
return '$return = $value !== null ? new \Doctrine\Common\Collections\ArrayCollection($value) : null;';
}
}
但是,当我更新文档时,它不会从集合中写入更改;最初的持久性工作正常。我做了一些温和的调试,发现UnitOfWork没有(重新)计算变化。
这是我的测试代码: 文件:
<?php
namespace Application\Blog\Domain\Document;
use Cob\Stdlib\String,
Doctrine\Common\Collections\ArrayCollection;
/**
* Blog category
*
* @Document(repositoryClass="Application\Blog\Domain\Repository\BlogRepository", collection="blog")
*/
class Category
{
/**
* @Id
*/
private $id;
/**
* @Field(type="arraycollection")
*/
private $slugs;
public function __construct()
{
$this->slugs = new ArrayCollection();
}
public function getId()
{
return $this->id;
}
public function getSlugs()
{
return $this->slugs;
}
public function addSlug($slug)
{
$this->slugs->add($slug);
}
}
服务:
<?php
$category = new Category("Test");
$category->addSlug("testing-slug");
$category->addSlug("another-test");
$this->dm->persist($category);
$this->dm->flush();
$this->dm->clear();
unset($category);
$category = $this->dm->getRepository("Application\Blog\Domain\Document\Category")->findOneBy(array("name" => "Test"));
$category->addSlug("is-it-working");
$this->dm->persist($category);
$this->dm->flush();
var_dump($category->getSlugs());
预期结果:
object(Doctrine\Common\Collections\ArrayCollection)[237]
private '_elements' =>
array
0 => string 'testing-slug' (length=12)
1 => string 'another-test' (length=12)
2 => string 'is-it-working' (length=13)
实际结果
object(Doctrine\Common\Collections\ArrayCollection)[237]
private '_elements' =>
array
0 => string 'testing-slug' (length=12)
1 => string 'another-test' (length=12)
答案 0 :(得分:2)
我尝试实施不同的更改跟踪政策,但我无法启动更新工作。
最后,我意识到它没有检测到更改,因为对象是通过引用传递的。如此简单的文档更新未被检测到,因为在与原始文档进行比较时它是相同的引用。
解决方案是在进行更改时克隆对象:
public function addSlug($slug)
{
$this->slugs = clone $this->slugs;
$this->slugs->add($slug);
}
回想起来,尽管使用“通知”的更改跟踪策略更加繁琐,但我认为它仍然是一个更好的解决方案。但是现在我将在以后克隆和重构。
答案 1 :(得分:0)
您可能需要使用其他更改跟踪政策。在这种情况下,我会选择Notify