自定义映射类型的问题

时间:2011-03-23 23:58:26

标签: doctrine mongodb

我正在使用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)

2 个答案:

答案 0 :(得分:2)

我尝试实施不同的更改跟踪政策,但我无法启动更新工作。

最后,我意识到它没有检测到更改,因为对象是通过引用传递的。如此简单的文档更新未被检测到,因为在与原始文档进行比较时它是相同的引用。

解决方案是在进行更改时克隆对象:

public function addSlug($slug)
{
    $this->slugs = clone $this->slugs;
    $this->slugs->add($slug);
}

回想起来,尽管使用“通知”的更改跟踪策略更加繁琐,但我认为它仍然是一个更好的解决方案。但是现在我将在以后克隆和重构。

答案 1 :(得分:0)

您可能需要使用其他更改跟踪政策。在这种情况下,我会选择Notify