2011-03-23 143 views
1

我使用学说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

我尝试推行不同的变化的跟踪策略,但我不能起床工作的更新。

最后,我实现,因为对象是通过引用传递它未检测的变化。所以文档的简单更新没有被发现,因为它与原始文档相比是相同的参考。

解决的办法是进行更改时克隆对象:

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

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

0

您可能需要使用不同的变化跟踪政策。在这种情况下,我会去与Notify

+0

我试过这个,但无法让它工作。我有一个替代工作。 – Cobby 2011-03-25 00:20:28