【问题标题】:JPA Criteria Builder: How to pass ArrayList to Oracle function?JPA Criteria Builder:如何将 ArrayList 传递给 Oracle 函数?
【发布时间】:2017-06-01 22:58:18
【问题描述】:

我有一个接受 POINTS%ROWTYPE 表的 Oracle 函数。我想使用 CriteriaBuilder 类从 JPA 调用此函数,该类具有数据库函数的功能。当我尝试构建查询时,它会抱怨 ArrayLists 不是函数的有效查询参数。

如何将 ArrayList 从 JPA 传入 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
) 

Oracle 类型:

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

JPA Criteria Builder 调用

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 次。)然后我想将该点数组传回函数进行处理。

我需要为这个函数使用标准生成器只是查询的一部分。

感谢您的帮助。

【问题讨论】:

  • 首先没有从java.fetch-oracle-table-type-from-stored-procedure-using-jdbc访问包级表类型的解决方案。其次,我认为没有机会使用标准 JPA 访问任何用户定义类型(UDT)。 (2.4 的 Exlipse 链接有一些扩展来实现这一点)。 @Andremoniy 描述的解决方案仅适用于 sql 级类型。

标签: java oracle jpa plsql openjpa


【解决方案1】:

这可能会有所帮助。正如它所描述的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);

【讨论】:

  • 我得到一个 java.sql.SQLException: Unsupported feature 异常。从一点点挖掘来看,似乎在 Oracle 中还有另一种方法可以做到这一点(OracleConnection.createARRAY()),所以我会研究一下,看看它是如何工作的。
  • 经过更多测试后,我似乎无法让我的阵列从 JPA 端与 Oracle SQL 级别类型啮合。我遵循了我发现的类似问题的建议(比如大写和使用 STRUCT),但由于某种原因它不想工作。由于截止日期,我不得不暂停该项目的这一部分,但看到您的回答使我走上了正确的道路,没有给出其他答案,代表您,谢谢。
猜你喜欢
  • 2015-05-11
  • 2021-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多