在我的項目中,我有一個JPA層次結構Location -> Site
。現在從層次結構中檢索的實體類
@Entity
@Table(name = "LOCATION")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="LOC_TYPE",discriminatorType=DiscriminatorType.STRING)
public class Location {
...
}
@Entity
@DiscriminatorValue("SI")
public class Site extends Location {
...
}
,每Employee
具有分配的Location
列表(就算了,據我所知,所有這些地方實際上是Site
)。在某些部分,我需要列出Site
s和Employee
已經分配給(注意,我定義的關係是Location
s)。
使用Hibernate 3.2,我可以只寫Location
的查詢並通過判別式過濾;返回的類是更具體的子類的實例,v.g:
Query query = em.createQuery("SELECT loc FROM Location loc WHERE loc.type=\"SI\"");
List<Location> locations = (List<Location>) query.getResultList();
for (Location location : locations) {
Site mySite = (Site) location;
...
}
但是,我無法找到,如果這種行爲是由JPA規範保證或告訴是從休眠只是一個實現決策的任何文件。在最後一種情況下,我不應該使用這種方法,因爲如果我切換提供者,它可能會改變)。
你能告訴我,如果我的方法是由標準支持?
順便說一句,我使用JPA 1基於Hibernate 3.2
UPDATE:
在奧登澄清我想要的東西,這就是「安全警報」,我已經實現。請記住,disc
屬性是鑑別器列,所以我確定返回的對象保持爲Site
實例。
Query query = em.createQuery("SELECT lo FROM Employee em JOIN em.location lo WHERE lo.disc = 'SI'");
List<Location> locations = (List<Location>) query.getResultList();
List<Site> site = new ArrayList<Site>();
for (Location location : locations) {
if (location instanceof Site) {
sites.add((Site) location);
} else {
log.warn("Found a Location that is not instance of Site");
}
}
JPA規範規定,我log.warn
聲明絕不會叫什麼名字? AFAIK,也許一個實現可以返回一堆Location
不是Site
的實例。當然,在這種情況下只有Location
屬性可用;該行爲有點像在C++中切片。
我想你還是沒有解釋你的問題。你有一個Java字段'disc',它被映射到'LOC_TYPE'數據庫列嗎?如果沒有,比你可以簡單地嘗試。另外在你的例子中:爲什麼不直接尋找Site實體:'SELECT s FROM Site s WHERE ...'? –
我的JPQL有點過分簡化了,現在它更具代表性。我不能只選擇「Site」實體,因爲我通過導航到「Location」超類。作爲最後一個解決方案,我可以用一個從'Location'返回ID來選擇'Site'的子選擇來解決這個問題,但這個問題讓我想到了這個問題(另外,我試圖避免' IN'子選擇表現問題)。 – SJuan76
1.子選擇比「IN」更差。 2.只要你沒有1000個值,'IN'從來就不是問題。 3.你對我的第一個想法(也許你已經使用過)沒有提出任何意見:只需添加一個映射到你的LOC_TYPE數據庫鑑別器列的JAVA字段eType,並在你的查詢中使用它。 –