2011-05-17 82 views
4

我想在Hibernate中實現一個非常簡單的繼承模型。基本上我有一個叫做A的超類,有幾個子類都從A繼承。由於我看到的行爲對於所有這些行爲都是相同的,因此他們可以被簡稱爲BJPA /休眠 - InheritanceType.JOINED行爲像InheritanceType.TABLE_PER_CLASS

我想要達到的是在6.2節中描述的here。基本上,應該有一個包含其字段的A的表格,以及一個B的表格,該表格僅包含與子類不同的字段,並且還有一個連接列,返回表A。我正在使用Hibernate的自動模式生成(僅爲開發持久性單元啓用)。

我看到模式時看到的是A包含其字段(正確)的表格和B的表格,其中包含A中的所有字段(不正確),以及添加的字段B。我的課程註釋如下:

@Entity 
@Table(name="A") 
@Inheritance(strategy = InheritanceType.JOINED) 
public class A implements Serializable { 
    protected long id; 
    protected Date createDate; 
    protected String title; 
    protected boolean hidden; 

    public A() { 
    } 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    public long getId() { 
     return id; 
    } 

    @Column(nullable = false) 
    @Temporal(TemporalType.TIMESTAMP) 
    public Date getCreateDate() { 
     return createDate; 
    } 

    @Column(nullable = false) 
    public boolean isHidden() { 
     return hidden; 
    } 

    @Column(nullable = false) 
    public String getTitle() { 
     return title; 
    } 

    //also setters... 
} 

@Entity 
@Table(name="B") 
@PrimaryKeyJoinColumn(name="aId", referencedColumnName="id") 
public class B extends A { 
    private String extraField; 

    public B() { 
     super(); 
    } 

    @Column 
    public String getExtraField() { 
     return extraField; 
    } 

    //also setter... 
} 

任何想法我做錯了什麼?具體來說,我想看看,當我查看生成的數據庫架構是一樣的東西:

Table A: {id, createDate, title, hidden} 
Table B: {aId, extraField} 

...而是我得到的是:

Table A: {id, createDate, title, hidden} 
Table B: {id, createDate, title, hidden, extraField} 

這是不可能的使用Hibernate自動模式生成,還是我搞砸了註釋的地方?

回答

4

你的註解是正確的,它應該產生你想要的表模式。

但是現在您會得到一個不希望的模式,這正是使用Table per concrete class策略生成​​的模式(即@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS))。所以,我認爲其中一個可能的原因是配置中的hibernate.hbm2ddl.auto屬性使用默認值,即update

update價值的行爲是:

  • Hibernate會嘗試創建一個 更新腳本時創建 的SessionFactory數據庫 架構更新到當前的映射。

  • 如果更新語句不能 執行,它會被跳過(對於 例如添加非空列到 表與現有的數據)

  • Hibernate不會在更新期間刪除任何數據 (例如,如果 列的名字改變了,它只是 用新名稱添加一個新列, 但仍保持與 原來的名字列)

因此,我認爲您必須使用@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)來生成之前的模式,從而生成以下模式。表A和表B沒有彼此的任何外鍵關聯。

Table A: {id, createDate, title, hidden} 
Table B: {id, createDate, title, hidden, extraField} 

之後,您更改爲使用@Inheritance(strategy = InheritanceType.JOINED)。在更新模式過程中,hibernate通過在TableA.idTableB.id之間添加外鍵關聯來更新您的方案。它保留了表B中的所有其他列。這就是爲什麼即使你的註釋是正確的,你也能得到當前的模式。

在啓動休眠程序之前,從數據庫中刪除表A和表B之後,應該生成所需的表模式。或者,您可以將hibernate.hbm2ddl.auto設置爲create,然後休眠將在生成表架構之前刪除所有表。

+0

謝謝,我不認爲我曾經使用'InheritanceType.TABLE_PER_CLASS',但在任何情況下刪除表並讓Hibernate重新生成架構,因爲您建議修正事情。 – aroth 2011-05-17 23:10:29