Почему вызов функции в прокси-объекте Doctrine указывает на родительский объект, а не на унаследованный дочерний объект?

Я создал унаследованный класс документа, см. код ниже. Документы сохраняются нормально, но при извлечении документа и попытке вызвать дочернюю функцию я получаю сообщение об ошибке Вызов неопределенного метода 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, Доктрина говорит: «Уведомление: неопределенный индекс: не простой (... )".

И что самое странное, как только я добавляю getPriceDefinition() в родительский класс (ProductBase), он вызывается корректно и без ошибок.

Эээ... это был длинный вопрос. Во всяком случае, я просто не могу понять, в чем здесь проблема. Это мой вызов getRepository('AcmeProductBundle:Product') или мои определения наследования...


person Ville Mattila    schedule 18.07.2012    source источник


Ответы (1)


Учитывая, что ProductBase является абстрактным, есть ли причина, по которой вы не аннотируете его как MappedSuperclass? ODM создает прокси, который расширяет ProductBase (он делает это между вашим вызовом findOneBy() и попыткой вызова getPriceDefinition()), что на практике не имеет смысла. Объекты прокси предназначены для взаимозаменяемого использования с отображаемым классом — в этом случае прокси расширяет абстрактный класс, который никогда не должен существовать сам по себе. Тем не менее, кажется, что это странное сопоставление вызывает ошибку в логике дискриминатора, поскольку это поле типа должно вызывать использование SimpleProduct.

Кроме того, изменение значения базы данных поля type на not-simple не должно приводить к тому, что код вызывает уведомление PHP. Вместо этого мы должны генерировать исключение.

Не могли бы вы создать отдельные проблемы для обеих этих ошибок в репозитории GitHub? Если вы готовы к этому, провальные тестовые примеры также будут приветствоваться.

person jmikola    schedule 29.07.2012
comment
Привет! Спасибо за ваш ответ. Я открою вопросы как можно скорее и буду обновлять этот вопрос / ответ. Спасибо! - person Ville Mattila; 02.08.2012
comment
Наконец, спустя полгода, я открыл задачи и добавил тестовые примеры: github.com/ доктрина/mongodb-odm/issues/562 для проблемы с абстрактным классом, github .com/doctrine/mongodb-odm/issues/563 для отсутствующего исключения. - person Ville Mattila; 19.04.2013