0

継承されたドキュメント クラスを作成しました。以下のコードを参照してください。ドキュメントは正常に保持されますが、ドキュメントをフェッチして子関数を呼び出そうとすると、子ドキュメントに getPriceDefinition() 関数があっても、未定義のメソッド Proxies__CG__\Acme\ProductBundle\Document\ProductBase::getPriceDefinition() への呼び出しというエラーが発生します。プロキシは、SimpleProduct ではなく、ProductBase も指しています。

親クラスの 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 と一致しない「単純」以外の値 (「単純ではない」など) に変更すると、Doctrine は「通知: 未定義のインデックス: 単純ではない (... )」。

そして、最も奇妙なことに、親クラス (ProductBase) に getPriceDefinition() を追加するとすぐに、エラーなしで適切に呼び出されます。

うーん...それは長い質問でした。とにかく、ここで何が問題なのかを見つけることができません。getRepository('AcmeProductBundle:Product') 呼び出しですか、それとも継承定義ですか...

4

1 に答える 1

0

それが抽象的であることを考えると、 MappedSuperclassProductBaseとして注釈を付けていない理由はありますか? ODM は ProductBase を拡張するプロキシを構築しています (これは、呼び出しと呼び出しの試行の間に行われます)。これは実際には意味がありません。プロキシ オブジェクトは、マップされたクラスと交換可能に使用されることを意図しています。この場合、プロキシは、単独では存在してはならない抽象クラスを拡張しています。それでも、この奇妙なマッピングがディスクリミネーターのロジックにバグを引き起こしているようです。その型フィールドが使用されるはずだからです。findOneBy()getPriceDefinition()SimpleProduct

また、typeフィールドのデータベース値を に変更してもnot-simple、コードが PHP 通知を引き出すことはありません。代わりに例外をスローする必要があります。

GitHub リポジトリでこれらのバグの両方について別々の問題を開いてもよろしいですか? 気が向いたら、テストケースの失敗も大歓迎です。

于 2012-07-29T04:26:57.350 に答える