2011-08-12 143 views
16

我遇到了我的映射問題。我無法讓它工作。我有這樣的抽象基類:當一個子類沒有額外屬性時,Doctrine表繼承類繼承

/** 
* @Entity 
* @Table(name="actions") 
* @InheritanceType("JOINED") 
* @DiscriminatorColumn(name="type", type="string") 
* @DiscriminatorMap({"FOO" = "FooAction", "BAR" = "BarAction", ...}) 
*/ 
abstract class AbstractAction 
{ 
    ... 
} 

我有一堆不同的行動,所有不同的領域。 E.g:

/** 
* @Entity 
* @Table(name="actions_foo") 
*/ 
class FooAction extends AbstractAction 
{ 
    ... 
} 

但是我的動作(BarAction)不需要除了由AbstractAction供應的任何額外的領域之一。但是,我怎麼能映射它?我嘗試省略@Table,或者使用與AbstractAction相同的@Table,但不起作用。

/** 
* @Entity 
* @Table(name="actions") 
*/ 
class BarAction extends AbstractAction 
{ 
    ... 
} 

省略@Table給了我一個PDOException有關缺失表BarAction。使用基類的@Table給我:

PDOException: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens 

所以,我怎麼映射呢?

編輯:到目前爲止,我已經嘗試了兩件事。

我試圖從BarAction中刪除@Entity以及@Table,希望這樣它不再需要數據庫表。這是行不通的。相反,我得到這個錯誤:

Doctrine\ORM\Mapping\MappingException: Class BarAction is not a valid entity or mapped super class. 

接下來我想在我的數據庫只是一個單一的外鍵列id創建actions_bar表。然後我將BarAction映射到它。這是有效的(耶!),但它感到骯髒和醜陋,有一個額外的SQL表,我根本不需要。

所以,還是找一個更好的辦法...

+0

借鑑了我在D2和這[文檔]方面的2年經驗(http://www.doctrine-project.org/docs/orm/2.0/en/reference/inheritance-mapping.html#class-table-inheritance ),只能使用一種類型的繼承。您可以選擇已連接的表繼承,併爲每個實體都有一個單獨的表,或者選擇一個表繼承,並將所有實體都放在一個表中。 (對於尚未有評論代表的WizardZ添加評論) – Oded

+4

基於我在D2和文檔方面的2年經驗:http://www.doctrine-project.org/docs/orm/2.0/en/reference/ inheritance-mapping.html#class-table-inheritance你只能使用一種類型的繼承。您可以選擇已連接的表繼承,併爲每個實體都有一個單獨的表,或者選擇一個表繼承,並將所有實體都放在一個表中。 – WizardZ

+0

@Sander:你的BarAction真的應該是'AbstractAction'的一個子類嗎?我不知道在你的域模型中是否有'BarAction'作爲層次結構的根,但是從實現的角度來看,這可以解決你的問題,因爲'BarAction'只會使用來自基地臺! – Benjamin

回答

2

您正在使用joined繼承模型(類表繼承),它爲父項和每個子項使用一個單獨的表。如果您沒有在子類中指定任何字段,則Doctrine只會創建一個僅包含ID字段的表。

而父類只能使用一種類型的繼承,無論是類表繼承還是單表繼承。

在這種情況下,如果您不想擁有隻有id列的表格,則需要更改數據模型。

2

也許這可以幫助或添加新的東西。這不是一個如何回答,而是簡單地理解概念。

如果你認爲類和你理解你的模型爲:AbstractAction,FooAction和BarAction可能是因爲你可以在子類上以不同的方式實現相同的方法,或者擴展父類方法。

如果您選擇使用表格表示這些類,並且選擇「帶鑑別符屬性的所有表」,我認爲您沒有問題。對於BarAction,您將註冊discriminator =「BarAction」,這將由BarAction.php實體類重新設置。

另一方面,如果你選擇使用不同的表格,我認爲你需要每個「班級」一張桌子。 BarAction表只包含AbstractAction的ID字段,但它需要將數據「分類」(或歧視)爲FooAction。

總之,我認爲三個表格代表三個類是一個很好的解決方案,儘管BarAction表只包含一個到父表的「鏈接」。

0

我想你不必在數據庫中手動創建表。

我有幾乎相同的結構,我讓Doctrine(2.3)做這項工作。儘管你必須在每個子類上放置@Entity et @Table。 錯誤 無效的參數編號:綁定變量的數量與令牌的數量不匹配 可能不相關。這可能是一個緩存問題,你試過沖洗它嗎?

0

我也遇到了這個問題,但我只是添加了一些虛擬屬性到我的繼承實體,認爲它可以在任何時候有用。我知道它不是完美的想法,但它幫助我保持了我的數據模型的完整性,並使我有可能在將來的繼承實體中擁有自己的屬性。