2013-02-24 32 views
1

在我爲我的項目提供新功能的工作中,我決定擴展模型。我決定使用基類,將通用的方法分組,並且只有很少的子類,都保存在一個集合中。Doctrine ODM返回代理對象的基類,而不是子分類的文檔

基地,抽象類:

/** 
* @MongoDB\Document(repositoryClass="EntryRepository") 
* @MongoDB\MappedSuperclass 
* @MongoDB\InheritanceType("SINGLE_COLLECTION") 
* @MongoDB\DiscriminatorField(fieldName="type") 
* @MongoDB\DiscriminatorMap({"entry"="Application_Model_Entry", "image"="Application_Model_Image", "movie"="Application_Model_Movie"}) 
*/ 
abstract class Application_Model_Entry 
{ 
    abstract function foo(); 
} 

一些具體類(我有幾個人,類似的,但有些是抽象的):

<?php 
/** @MongoDB\Document */ 
class Application_Model_Image extends Application_Model_Entry 
{ 
    function foo() 
    { 
     return 'foo'; 
    } 
} 

過渡後,我打開我的索引頁面,並出現一個錯誤 - PHP試圖調用抽象方法,因爲Doctrine返回的對象是基類類的代理。我想這是因爲我改名從Application_Model_Image收集到Application_Model_Entry和內部對象引用(的DBRef$ref領域)仍然指向Application_Model_Image,但我注意到一些有趣的:總是第一個查詢結果的具體類的適當的文件,其餘的都是基類代理 - 在我從數據庫中刪除第一個對象後,第二個對象變好了。

在單個對象顯示頁面上,所有對象都可以正常工作,所以我想也許這是Zend Framework的頁面類迭代結果的一些問題,所以我跳過了尋呼機並直接從查詢中刪除對象。我打印了100個第一個結果的類,其中一些有適當的類(Snippet of that list on pastebin)。我查看了數據庫,但我沒有注意到這些數據(working vs not working)。我想也許這是引用錯誤,但正如我上面寫的,如果它是第一個結果列表中的相同的對象可以工作。

任何想法或提示?我可以調試更多,但我需要被告知在Doctrine的代碼裏面看什麼。

+1

'Document'註釋不應該與'MappedSuperclass'一起使用。前者用於具體實現,後者用於抽象類。我不理解有關查詢結果超出第一個代理對象的位,因爲代理只能在ReferenceOne/Many關係的上下文中創建爲佔位符。 – jmikola 2013-02-25 16:11:38

+0

查詢結果就像我在第一個pastebin鏈接中顯示的一樣 - 第一個是具體類,其餘大部分是代理(ProjectProxy \ __ CG __ \ Application_Model_Entry具體)。刪除''文檔''註釋後,一切似乎都很好,非常感謝。 目前情況並非如此,但如果我想,我還可以指示整個繼承樹的集合名稱嗎? – leafnode 2013-02-25 19:42:58

+0

我不相信'MappedSuperclass'支持任何選項,所以你必須做實驗。所有繼承類仍然應該按照單個集合繼承映射存儲在同一個集合中,但名稱本身可能最終將從抽象類的名稱派生。 – jmikola 2013-02-25 20:02:59

回答

5

通過上面的jmikola評論,我刪除了Document註釋,並且一切都開始順利進行。奇怪的結果讓我在錯誤的地方尋找錯誤,但幸運的是我在這裏得到了一個提示。

爲後人:

  • Document標註爲具體的類
  • MappedSuperclass註釋是抽象類
  • 如果您在查詢結果中獲得的代理類對象,則可能是在該部門有一個查詢股價
  • 即使沒有Document註釋,也可以指示鑑別符字段/值。
相關問題