2012-10-31 50 views
1

我們在那裏有一個函數的索引(數據庫是Oracle)數據表使用基於函數的索引。但是,在我們的Java EE EJB應用程序,系統訪問使用JPA查詢的數據。甲骨文:如何在容器中產生的JPA查詢的WHERE子句

但爲了迫使Oracle使用的,而不是做一個全表掃描基於函數的索引,我需要一種方法來告訴JPA容器生成的WHERE子句中的指數函數定義的SQL sql查詢。

據我所知,我們必須使用原生查詢用於創建這樣生成的查詢定製。但爲了使用本機查詢,我們要做大量的代碼修改。 任何人都可以請提出任何其他變通方法解決這一問題?

指數:(我們需要強制執行唯一約束的DEV_ID + Dev_Type,但有時DEV_ID可以爲空,而Dev_Type可以重複。)

(NVL2(Dev_Id, Dev_Id, NULL), NVL2(Dev_Id, Dev_Type, NULL)) 

查詢,我們需要:(爲了

Select * from some_table where NVL2(Dev_Id, Dev_Id, NULL) = 'some_val'; 

集裝箱使用索引)生成的查詢:

Select * from some_table where Dev_Id = 'some_val'; 
+1

是不是'NVL2(Dev_Id,Dev_Id,NULL)'冗餘?而你就不能添加在DEV_ID的指數? – eaolson

+0

@eaolson我們的DBA表示它不適用於某些有效值,但我想知道爲什麼發生這種情況,因爲NVL2(Dev_Id,Dev_Id,NULL)和Dev_Id基本相同。我無法得到他所談論的價值。我會再次檢查。謝謝。 –

+0

@eaolson DBA表示我們不能添加像(Dev_Id,NVL2(Dev_Id,Dev_Type,NULL))這樣的唯一索引,因爲那麼oracle將不會允許Dev_Id的NULL值。這很奇怪,但我沒有時間去測試它以確認。 –

回答

1

也許創建一個視圖並讓JPA通過這是一個選項?

CREATE VIEW SOME_VIEW AS SELECT SOME_TABLE.*, 
    NVL2(Dev_Id, Dev_Id, NULL) AS NVL_DEV_ID FROM SOME_TABLE; 


SELECT * FROM SOME_VIEW WHERE NVL_DEV_ID = ? 

或者表上的虛擬列的計算結果爲函數?

1

JPA 2.1包括FUNCTION運營商,允許調用特定DB-功能:

from SomeEntity where function('NVL2', devId, devId, null) = 'some_val'; 

如果你沒有JPA 2.1可用,但使用的EclipseLink> = 2.4,你也可以使用FUNCTION,如它可用作Eclipselink擴展。

如果你有EclipseLink的2.3.x版本,你沒有FUNCTION,但你可以使用等效FUNC這是作爲一個的EclipseLink擴展。