2017-01-17 16 views
7

我有一個Oracle函數,它包含POINTS%ROWTYPE表。我想使用CriteriaBuilder類從JPA調用這個函數,它具有數據庫函數的功能。當我嘗試構建查詢時,它會死抱怨ArrayLists不是函數的有效查詢參數。JPA Criteria Builder:如何將ArrayList傳遞給Oracle函數?

如何從JPA傳遞ArrayList到Oracle函數?

Oracle函數簽名:

CREATE OR REPLACE FUNCTION LOCATION_CONTAINS 
(
LATITUDE_IN IN DOUBLE PRECISION, 
LONGITUDE_IN IN DOUBLE PRECISION, 
points IN types_pkg.point_array, 
numPoints IN INTEGER 
) 

甲骨文類型:

create or replace package types_pkg 
as 
type point_array is table of FILTERPOINT%ROWTYPE; 
end types_pkg; 

JPA標準構建器調用

List<FilterPoint> points = getPoints(location_name); 
int numPoints = points.size(); 

Expression ex = 
      cb.function("LOCATION_CONTAINS", 
      Integer.class, 
      entity.get("latitude"), 
      entity.get("longitude"), 
      cb.literal(points), 
      cb.literal(numPoints)); 

例外:

org.apache.openjpa.persistence.ArgumentException: 
The specified parameter of type "class middle.ware.FilterPoint" is not a valid query parameter. 

本質上,我想抓取一個函數調用外的點的數組,所以我只需要抓取一次(現在我在函數調用內部進行選擇,所以每調用一次該函數就會運行一次,這是潛在的100,000次)。然後,我想將這些點數傳回給函數進行處理。

我需要使用條件生成器來完成這個功能只是查詢的一部分。

感謝您的任何幫助。

+0

首先沒有解決訪問從Java包級的表型[獲取Oracle的表型從 - 存儲過程-使用-JDBC(http://stackoverflow.com/questions/6410452/fetch-oracle-table-type-from-stored-procedure-using-jdbc)。 Secound我認爲沒有機會使用標準JPA訪問任何用戶定義類型(UDT)。 (從2.4的Exlipse鏈接有一些擴展來實現這一點)。 @Andremoniy描述的解決方案僅適用於sql級別的類型。 –

回答

3

這可能有所幫助。如其描述here,用於用戶定義的TABLE類型的適當Java類型是java.sql.Array。我想你需要把你的列表轉換成這種類型。其中一個可能的方式來做到這一點,只需調用methodcreateArrayOf你的連接(見本answer):

Session session = (Session)em.getDelegate(); 
Connection conn = session.connection(); 
String[] data = points.toArray(new FilterPoint[points.size()]); 
java.sql.Array sqlArray = conn.createArrayOf(typeName, data); 
+0

我得到一個java.sql.SQLException:不支持的功能異常。從一點點挖掘,看起來還有另外一種方法可以在Oracle中專門做(OracleConnection.createARRAY()),所以我會仔細研究一下,看看它是如何工作的。 – GuitarStrum

+1

經過更多測試後,我似乎無法從JPA端獲取我的數組以與Oracle SQL-Level類型進行網格劃分。我遵循了我發現的類似問題(如大寫和使用STRUCT)的建議,但出於某種原因,它不想工作。由於截止日期的原因,我不得不將這部分項目暫時擱置,但看到你的回答使我走上了正確的道路,沒有人給出其他答案,代表你,並且感謝你。 – GuitarStrum