2017-01-17 2 views
7

Ich habe eine Oracle-Funktion, die eine Tabelle von POINTS% ROWTYPE aufnimmt. Ich möchte diese Funktion von JPA mit der CriteriaBuilder-Klasse aufrufen, die eine Funktion für Datenbankfunktionen hat. Wenn ich versuche, die Abfrage zu erstellen, stirbt sie und beschwert sich darüber, dass ArrayLists keine gültigen Abfrageparameter für die Funktion sind.JPA Criteria Builder: Wie wird ArrayList an die Oracle-Funktion übergeben?

Wie kann ich in einer Arraylist von PPV in eine Oracle-Funktion übergeben?

Oracle Funktion Unterschrift:

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 
) 

Oracle Typ:

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

JPA Kriterien Builder Aufruf

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)); 

Ausnahme:

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

Im Grunde möchte ich eine Reihe von Punkten außerhalb des Funktionsaufrufes greifen, so dass nur ich habe es einmal zu holen (jetzt ich die Auswahl innerhalb des Funktionsaufrufes zu tun, so dass es jedes Mal läuft ist die Funktion aufgerufen wird, die potentiell ist 100.000 Mal.) Dann möchte ich dieses Array von Punkten zurück in die Funktion für die Verarbeitung übergeben.

Ich brauche Kriterien Builder für diese Funktion zu benutzen, ist nur die Abfrage Teil.

Danke für jede Hilfe.

+0

Erstens gibt es keine Lösung auf Paketebene Tabellentyp von Java zugreifen [Fetch-oracle-Tabelle -Typ-from-gespeicherten-Prozedur betriebene-JDBC] (http://stackoverflow.com/questions/6410452/fetch-oracle-table-type-from-stored-procedure-using-jdbc). Secound Ich denke, dass es keine Möglichkeit gibt, auf einen beliebigen Benutzerdefinitionstyp (UDT) unter Verwendung von Standard-JPA zuzugreifen. (Exlipse Link von 2.4 hat eine Erweiterung, um dies zu erreichen). Die von @Andremoniy beschriebene Lösung funktioniert nur für SQL-Level-Typen. –

Antwort

3

helfen Dies könnte. Wie es here beschrieben, entsprechende Java-Typ für benutzerdefinierte TABLE Typ ist java.sql.Array. Ich nehme an, Sie müssen Ihre Liste in diesen Typ konvertieren. Eine der Möglichkeiten, es zu tun, rufen Sie einfach methodcreateArrayOf auf der Verbindung (siehe auch diese 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

Ich bekomme eine java.sql.SQLException: Nicht unterstützte Feature-Ausnahme. Von ein wenig graben, es sieht aus wie es gibt eine andere Möglichkeit, es in Oracle speziell (OracleConnection.createARRAY()) zu tun, also werde ich einen Blick darauf werfen und sehen, wie das funktioniert. – GuitarStrum

+1

Nach weiteren Tests kann ich mein Array anscheinend nicht von der JPA-Seite beziehen, um mit dem Oracle-SQL-Level-Typ zu interagieren. Ich habe Ratschläge von ähnlichen Fragen, die ich gefunden habe (wie Großschreibung und Verwendung eines STRUCT), gefolgt, aber aus irgendeinem Grund wollte es nicht funktionieren. Ich musste diesen Teil des Projekts aufgrund von Deadlines auf Eis legen, aber da deine Antwort mich auf den richtigen Weg geführt hat und keine andere Antwort gegeben wurde, bin ich für dich und danke dir. – GuitarStrum

Verwandte Themen