2017-02-10 4 views
1

私はこの問題があります。いくつかの基本文書を拡張するいくつかの文書があります。これらの文書には、ユーザーがメモを追加できるような種類のメモ機能があります。私は別のコレクション(それは検索可能である必要があり、埋め込むことはできません)に格納されているノート文書を持ち、そのノートが属する文書を参照するownerプロパティを持っています。私はトラブルの教義でこれをモデル化します:Doctrine ODM双方向参照(継承あり)

<?php 

/** @ODM\MappedSuperclass */ 
abstract class Base { 
    /** @ODM\Id */ 
    public $id; 

    /** @ODM\ReferenceMany(targetDocument="Note", mappedBy="owner") */ 
    public $notes; 
} 


/** @ODM\Document */ 
class MyDocument extends Base { 
    /** @ODM\String */ 
    public $name; 
} 


/** @ODM\Document */ 
class Note { 
    /** @ODM\Id */ 
    public $id; 

    /** @ODM\ReferenceOne(targetDocument="Base", inversedBy="notes") */ 
    public $owner; 

    /** @ODM\String */ 
    public $text; 
} 

$mdoc = new MyDocument; 
$note = new Note; 

$mdoc->name = 'foo'; 
$note->text = 'bar'; 

$mdoc->notes[] = $note; 
$note->owner = $mdoc; 

$dm->persist($mdoc); 
$dm->persist($note); 

$dm->flush(); 

$dm->clear(); 

$note2 = $dm->find(Note::class, $note->id); 
echo $note2->owner->name; 

をそして私が得る:注意:未定義のプロパティ:Proxies__CG __ \基本:: $名を。他の例で私は:識別子 "XXX"を持つ "Proxies__CG __ \ベース"文書が見つかりませんでした。

明らかに、MyDocumentではなくBaseクラスを読み込もうとします。正しいクラスをロードする方法私はBaseとしてMappedSuperclassを設定し、discriminatorフィールドを設定し、targetDocumentなどを省略しました。そして、期待どおりに動作せず、さまざまなエラー/間違った動作で終了します。

これも可能ですか?

おそらく関連:

注:それらのどれも本当に助けていないか、私が何かを逃しました。

答えて

2

あなたは、基本クラスのための弁別定義が欠落している:あなたがいることをしたら予想通り

/** 
* @ODM\MappedSuperclass 
* @ODM\InheritanceType("COLLECTION_PER_CLASS") 
* @ODM\DiscriminatorField("type") 
* @ODM\DiscriminatorMap({ 
*  "document"=MyDocument::class 
* }) 
*/ 
abstract class Base { 
    // ... 
} 

は、それが動作するはずです。継承タイプは、同一または異なるコレクションに文書を保存するかどうかによって、SINGLE_COLLECTIONにすることもできます。

+0

ありがとうございます。ちょうどメモ:最低限必要な部分はDiscriminatorFieldです(私はIDがデフォルト値を持っていると思っていました)。継承型は省略することができます(クラスごとのコレクションはデフォルトです)。また、識別子もマップします(クラス名を保存します)。 –

+1

ああ、そこには注意してください。継承型は、デフォルトでは「none」です。開発中に気づかないかもしれませんが、継承型を設定しない限り、メタデータキャッシュは識別子フィールドを省略します。次のバグ修正リリースではこれが修正されます(詳細はPR [#1556](https://github.com/doctrine/mongodb-odm/pull/1556)を参照)。それまでは、生産上のトラブルを避けるために継承タイプを設定してください。 – alcaeus

関連する問題