【问题标题】:Why a function call in Doctrine's proxy object points to parent object instead of inherited child object?为什么 Doctrine 的代理对象中的函数调用指向父对象而不是继承的子对象?
【发布时间】:2012-07-29 12:26:57
【问题描述】:

我创建了一个继承的文档类,见下面的代码。文档可以正常保存,但是在获取文档并尝试调用子函数时,我会收到错误 Call to undefined method Proxies__CG__\Acme\ProductBundle\Document\ProductBase::getPriceDefinition() 甚至是孩子文档具有 getPriceDefinition() 函数。代理也指向 ProductBase,而不是 SimpleProduct。

父类ProductBase.php

<?php
namespace Acme\ProductBundle\Document;

use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;

/**
 * @MongoDB\Document
 * @MongoDB\InheritanceType("SINGLE_COLLECTION")
 * @MongoDB\DiscriminatorField(fieldName="type")
 * @MongoDB\DiscriminatorMap({"simple"="SimpleProduct"})
 */
abstract class ProductBase
{   
    /**
     * @MongoDB\Id;
     */
    protected $_id;

    /**
     * @MongoDB\String
     */
    public $comment;
}

子类 SimpleProduct.php

<?php
namespace Acme\ProductBundle\Document;

use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;

/**
 * @MongoDB\Document
 */
class SimpleProduct extends ProductBase
{

    /**
     * @var PriceDefinition
     * @MongoDB\EmbedOne(targetDocument="PriceDefinition") 
     */
    protected $priceDefinition;

    public function getPriceDefinition() {
        return $this->priceDefinition;
    }
}

调用代码(仅部分):

$product = $this->dm->getRepository('AcmeProductBundle:Product')->findOneBy(array('_id' => $productId));
$priceDefinition = $product->getPriceDefinition(); // The error is thrown here

最后是数据库中的文档(即与上述文档正确持久化)。

{
  "_id": ObjectId("5006d7b76803fa9403000007"),
  "priceDefinition": {
     "referenceValue": 1000000,
     "currency": "iso: EUR",
     "taxBehavior": "fi_vat_a",
     "isGrossPrice": false
  },
  "type": "simple"
}   

总的来说,Doctrine 似乎无法识别返回的对象是子类。但是-例如,如果我将数据库类型值更改为与 DiscriminatorMap 不匹配的“简单”(例如“非简单”)以外的其他值,则该学说会显示“注意:未定义索引:非简单(... )”。

最奇怪的是,只要我在父类 (ProductBase) 中添加 getPriceDefinition(),它就会被正确调用且没有错误。

呃……这是一个很长的问题。无论如何,我只是无法找出这里有什么问题。是我的 getRepository('AcmeProductBundle:Product') 调用,还是我的继承定义...

【问题讨论】:

    标签: doctrine-orm doctrine-odm


    【解决方案1】:

    鉴于ProductBase 是抽象的,您是否有任何理由不将其注释为MappedSuperclass? ODM 正在构建一个扩展 ProductBase 的代理(它在您的 findOneBy() 调用和尝试调用 getPriceDefinition() 之间这样做),这在实践中没有意义。代理对象旨在与映射类互换使用——在这种情况下,代理正在扩展一个永远不应该单独存在的抽象类。即便如此,这种奇怪的映射似乎导致了鉴别器逻辑中的错误,因为该类型字段应该导致使用 SimpleProduct

    此外,将 type 字段的数据库值更改为 not-simple 不应导致代码引发 PHP 通知。我们应该抛出一个异常。

    您介意在GitHub repository 中为这两个错误打开单独的问题吗?如果您愿意,也欢迎失败的测试用例。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多