Hsqldb - Return 来自存储过程的结果集
Hsqldb - Return a Result Set from Stored Proc
我正在尝试调用 HsqlDB 中的存储过程和 return 结果集
我的存储过程如下
CREATE PROCEDURE p_getTeamTasksForLastXDays(IN teamId BIGINT, IN numberOfDays BIGINT) READS SQL DATA
DYNAMIC RESULT SETS 1
BEGIN ATOMIC
declare curs cursor for select taskId, taskName from V_TASK_DETAILS;
open curs;
END;
/;
我用来调用这个过程的 Java 和休眠代码如下
public void getTaskExecutionLogs(Long teamId, Long numberOfDays) {
LOG.info("Entered getTaskExecutionLogs Method - teamId:{}, numberOfDays: {}", teamId, numberOfDays);
ProcedureCall procedureCall = currentSession().createStoredProcedureCall("p_getTeamTasksForLastXDays");
procedureCall.registerParameter( TEAM_ID, Long.class, ParameterMode.IN ).bindValue( teamId );
procedureCall.registerParameter( NUMBER_OF_DAYS, Long.class, ParameterMode.IN ).bindValue( numberOfDays );
ProcedureOutputs outputs = procedureCall.getOutputs();
ResultSetOutput resultSetOutput = (ResultSetOutput) outputs.getCurrent();
List resultSetList = resultSetOutput.getResultList();
}
当我试图调用这个过程时得到的错误如下
java.lang.ClassCastException: org.hibernate.result.internal.UpdateCountOutputImpl cannot be cast to org.hibernate.result.ResultSetOutput
at com.mct.dao.database.impl.TaskDetailsDAOImpl.getTaskExecutionLogs(TaskDetailsDAOImpl.java:229)
当我尝试在 MySql
中调用存储过程时,完全相同的代码工作正常
非常感谢任何帮助
谢谢
达米安
ProcedureOutputs
是 interface
其中 extends
Outputs
(source).
ResultSetOutput
是 interface
其中 extends
Output
(source)。
当你调用 Outputs
的 getCurrent()
时,你会得到一个 Output
(source).
基本上,您期望转换是正确的,因为您将结果转换为 Output
的子接口。你正在做的事情叫做downcast。让我们看看案例。
您想将一个对象转换为另一个对象。向下转换可能是可能的,因为 ResultSetOutput
extends
Output
。由于向下转换可能是可能的,因此不会出现编译时错误,并且在可能的情况下,例如在 MySQL 中调用存储过程时,向下转换会成功。但是,当无法进行向下转换时,您会得到一个运行时异常。在我们的特定情况下,向下转换是不可能的,因为 .getOutputs
returns 另一个分类,可能是另一个继承分支上的子接口,如 UpdateCountOutput.
Lajos 对沮丧的看法是正确的。问题是您在假设 ProcedureOutputs.getCurrent()
返回的 Output
将是 ResultSetOutput
的情况下进行编码,而实际上,它可能是 UpdateCountOutput
.
其实Output
接口有一个方法isResultSet()
可以帮你判断:
boolean org.hibernate.result.Output.isResultSet()
Determine if this return is a result (castable to ResultSetOutput
). The alternative is that it is an update count (castable to UpdateCountOutput
).
Returns:
true
indicates that this can be safely cast to ResultSetOutput
), other wise it can be cast to UpdateCountOutput
.
除此之外,Outputs
可以传递多个Output
并且Output.getCurrent()
的状态由Output.goToNext()
控制。
因此,为了正确处理多个结果,您必须使用如下内容获取输出:
ProcedureOutputs outputs = procedureCall.getOutputs();
do {
Output current = outputs.getCurrent();
if (current.isResultSet()) {
ResultSetOutput resultSetOutput = (ResultSetOutput) current;
System.out.println("do something with result set output");
} else {
UpdateCountOutput updateCountOutput = (UpdateCountOutput) current;
System.out.println("do something with update count output");
}
} while (outputs.goToNext());
outputs.release();
在我的测试中我得到:
1647 [main] DEBUG org.hibernate.SQL - {call p_getTeamTasksForLastXDays(?,?)}
Hibernate: {call p_getTeamTasksForLastXDays(?,?)}
1668 [main] DEBUG org.hibernate.result.internal.OutputsImpl - Building Return [isResultSet=false, updateCount=0, extendedReturn=false
do something with update count output
1669 [main] DEBUG org.hibernate.result.internal.OutputsImpl - Building Return [isResultSet=true, updateCount=-1, extendedReturn=false
1671 [main] DEBUG org.hibernate.loader.Loader - Result set row: 0
1671 [main] DEBUG org.hibernate.loader.Loader - Result row:
do something with result set output
PS:我这里没有mysql,所以我无法确认它是否returns同时ResultSetOutput
和UpdateCountOutput
但在不同的order 比 hsqldb,但也许你可以验证一下。
我正在尝试调用 HsqlDB 中的存储过程和 return 结果集
我的存储过程如下
CREATE PROCEDURE p_getTeamTasksForLastXDays(IN teamId BIGINT, IN numberOfDays BIGINT) READS SQL DATA
DYNAMIC RESULT SETS 1
BEGIN ATOMIC
declare curs cursor for select taskId, taskName from V_TASK_DETAILS;
open curs;
END;
/;
我用来调用这个过程的 Java 和休眠代码如下
public void getTaskExecutionLogs(Long teamId, Long numberOfDays) {
LOG.info("Entered getTaskExecutionLogs Method - teamId:{}, numberOfDays: {}", teamId, numberOfDays);
ProcedureCall procedureCall = currentSession().createStoredProcedureCall("p_getTeamTasksForLastXDays");
procedureCall.registerParameter( TEAM_ID, Long.class, ParameterMode.IN ).bindValue( teamId );
procedureCall.registerParameter( NUMBER_OF_DAYS, Long.class, ParameterMode.IN ).bindValue( numberOfDays );
ProcedureOutputs outputs = procedureCall.getOutputs();
ResultSetOutput resultSetOutput = (ResultSetOutput) outputs.getCurrent();
List resultSetList = resultSetOutput.getResultList();
}
当我试图调用这个过程时得到的错误如下
java.lang.ClassCastException: org.hibernate.result.internal.UpdateCountOutputImpl cannot be cast to org.hibernate.result.ResultSetOutput
at com.mct.dao.database.impl.TaskDetailsDAOImpl.getTaskExecutionLogs(TaskDetailsDAOImpl.java:229)
当我尝试在 MySql
中调用存储过程时,完全相同的代码工作正常非常感谢任何帮助
谢谢 达米安
ProcedureOutputs
是 interface
其中 extends
Outputs
(source).
ResultSetOutput
是 interface
其中 extends
Output
(source)。
当你调用 Outputs
的 getCurrent()
时,你会得到一个 Output
(source).
基本上,您期望转换是正确的,因为您将结果转换为 Output
的子接口。你正在做的事情叫做downcast。让我们看看案例。
您想将一个对象转换为另一个对象。向下转换可能是可能的,因为 ResultSetOutput
extends
Output
。由于向下转换可能是可能的,因此不会出现编译时错误,并且在可能的情况下,例如在 MySQL 中调用存储过程时,向下转换会成功。但是,当无法进行向下转换时,您会得到一个运行时异常。在我们的特定情况下,向下转换是不可能的,因为 .getOutputs
returns 另一个分类,可能是另一个继承分支上的子接口,如 UpdateCountOutput.
Lajos 对沮丧的看法是正确的。问题是您在假设 ProcedureOutputs.getCurrent()
返回的 Output
将是 ResultSetOutput
的情况下进行编码,而实际上,它可能是 UpdateCountOutput
.
其实Output
接口有一个方法isResultSet()
可以帮你判断:
boolean org.hibernate.result.Output.isResultSet()
Determine if this return is a result (castable to
ResultSetOutput
). The alternative is that it is an update count (castable toUpdateCountOutput
).Returns:
true
indicates that this can be safely cast toResultSetOutput
), other wise it can be cast toUpdateCountOutput
.
除此之外,Outputs
可以传递多个Output
并且Output.getCurrent()
的状态由Output.goToNext()
控制。
因此,为了正确处理多个结果,您必须使用如下内容获取输出:
ProcedureOutputs outputs = procedureCall.getOutputs();
do {
Output current = outputs.getCurrent();
if (current.isResultSet()) {
ResultSetOutput resultSetOutput = (ResultSetOutput) current;
System.out.println("do something with result set output");
} else {
UpdateCountOutput updateCountOutput = (UpdateCountOutput) current;
System.out.println("do something with update count output");
}
} while (outputs.goToNext());
outputs.release();
在我的测试中我得到:
1647 [main] DEBUG org.hibernate.SQL - {call p_getTeamTasksForLastXDays(?,?)}
Hibernate: {call p_getTeamTasksForLastXDays(?,?)}
1668 [main] DEBUG org.hibernate.result.internal.OutputsImpl - Building Return [isResultSet=false, updateCount=0, extendedReturn=false
do something with update count output
1669 [main] DEBUG org.hibernate.result.internal.OutputsImpl - Building Return [isResultSet=true, updateCount=-1, extendedReturn=false
1671 [main] DEBUG org.hibernate.loader.Loader - Result set row: 0
1671 [main] DEBUG org.hibernate.loader.Loader - Result row:
do something with result set output
PS:我这里没有mysql,所以我无法确认它是否returns同时ResultSetOutput
和UpdateCountOutput
但在不同的order 比 hsqldb,但也许你可以验证一下。