2013-01-16 36 views
1

我使用OpenJPA加入繼承策略(InheritanceType.JOINED - 所以超類中的所有字段都有一個表,並且子類表只包含添加的所有字段的字段子類,加上一個返回超類表的引用)。 比方說,我有一個超類的人,以及一些子類:TypeAPerson,TypeBPerson等具有查詢時,如:OpenJPA加入繼承 - 避免數據庫連接

@NamedQuery(
name="Person.findByName", 
query="SELECT p FROM Person p WHERE p.name = :name") 

至於我很熟悉,我不會得到一個Person實例,但正確的子類實​​例。 正如here所述,爲了實現這一點並獲得適當的子類,OpenJPA將進行多個連接(每個子類一個連接)。這有很糟糕的表現,特別是如果我有很多子類。 我的問題是,如果有任何方法可以通過給JPA提示哪個表加入來避免這種情況?我想到的第一件事就是使用Discriminator值。 OpenJPA支持使用加入策略的判別器,所以它應該能夠從判別器值中確定一個子類(並因此加入一個適當的表)?有沒有辦法做到這一點? 有沒有其他方法可以避免不必要的數據庫連接?

+0

我不是專家,但DiscriminatorColumn可能是解決方案。請查看Joined Inheritance and DiscriminatorColumn usage [here](http://wiki.eclipse.org/EclipseLink/Examples/JPA/Inheritance)的完整示例。 – perissf

回答

1

如果你只需要一個子類的實體,那麼避免多餘連接的最好方法就是查詢這個子類。使用你的榜樣,它看起來是這樣的:

@NamedQuery(
name="Student.findByName", 
query="SELECT s FROM Student s WHERE s.name = :name") 

StudentPerson一個子類。當然,命名查詢應該在適當的子類上定義。

沒有辦法讓它兩種方式 - 使用超類查詢並只加入一個子類表。持久性提供者事先不知道結果,唯一正確提示的方法是搜索子類。

編輯:如果你不知道確切的子類,但可以限制可能sublasses,您可以使用JPQL TYPE關鍵字與IN子句,像這樣:

queryString="SELECT p FROM Person p WHERE p.name = :name AND TYPE(p) IN (Student, Teacher)" 

使用實體名稱作爲TYPE的參數。 AFAIK,它是區分大小寫的。實際的鑑別器類型和值並不重要,因爲你不查詢它。類型解析由提供者完成。

但我不確定是否會使提供者限制必要的連接。如果你最終使用或基準測試,請告訴它是否。

+0

謝謝你的回答。不幸的是,這個選項不適合我的情況。我有一種情況,我知道Person.Id,但我不知道它的類型,所以我不能查詢特定的子類。這就是爲什麼我詢問鑑別器的原因 - 我現在能想到的唯一方法是做兩個查詢:選擇一個Person,然後根據鑑別器值,查詢適當的子類。但是,這似乎很奇怪,因爲鑑別器被用來解析子類,所以JPA不支持它。 – Ana

+0

@一 - 我明白了。有一種不同的可能性,我以前沒有想過使用TYPE關鍵字。請參閱編輯。 – kostja