ORA-08103: 对象不再存在: Oracle 过程从 MyBatis 返回 Refcursor 时发生此错误
当在 Oracle 中调用存储过程返回 refcursor 时,我收到一个错误,
2011-05-10 03:36:23 DirtiesContextTestExecutionListener [DEBUG] After test method: context [[TestContext@3a363a36 testClass = AccountActivityServiceTest, locations = array<String>['classpath:/com/bnymellon/pwb/pfdetails/service/test/test-application-context.xml'], testInstance = com.bnymellon.pwb.pfdetails.service.test.AccountActivityServiceTest@6d2c6d2c, testMethod = getData@AccountActivityServiceTest, testException = org.springframework.jdbc.UncategorizedSQLException:
### Error updating database. Cause: java.sql.SQLException: ORA-08103: object no longer exists
### The error may involve com.bnymellon.pwb.pfdetails.persistence.AccountActivityMapper.getAccountActivityData-Inline
### The error occurred while setting parameters
### Cause: java.sql.SQLException: ORA-08103: object no longer exists
; uncategorized SQLException for SQL []; SQL state [72000]; error code [8103]; ORA-08103: object no longer exists
; nested exception is java.sql.SQLException: ORA-08103: object no longer exists
我正在使用 Spring MyBatis 集成项目。 MyBatis的版本是3.0.4
我可以看到Procedure正在执行。日志如下。
2011-05-10 03:36:16 PreparedStatement [DEBUG] ==> Executing: {call PWMWI.PAM_TRANSACTION_PKG.ACCOUNT_ACTIVITY( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)}
2011-05-10 03:36:16 PreparedStatement [DEBUG] ==> Parameters: 1987(Integer), 5627(Integer), null, null, 2010-01-01(Date), 2010-12-31(Date), All Asset Classes(String), [All, PYR](String), (String), null
我的 Mapper XMl 如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bnymellon.pwb.pfdetails.persistence.AccountActivityMapper">
<select id="getAccountActivityData"
parameterType="com.bnymellon.pwb.pfdetails.common.AccountActivityDTO"
statementType="CALLABLE">
{call PWMWI.PAM_TRANSACTION_PKG.ACCOUNT_ACTIVITY(
#{userInstance,mode=IN, jdbcType=INTEGER},
#{accountGroupId,mode=IN,
jdbcType=INTEGER},
#{accountId,mode=IN, jdbcType=VARCHAR},
#{accountId,mode=IN, jdbcType=VARCHAR},
#{startDate,mode=IN,
jdbcType=DATE},
#{endDate,mode=IN, jdbcType=DATE},
#{assetClass,mode=IN, jdbcType=VARCHAR},
#{transactionType,mode=IN,
jdbcType=VARCHAR},
#{cusipId,mode=IN, jdbcType=VARCHAR},
#{ticker,mode=IN, jdbcType=VARCHAR},
#{domainList,mode=OUT,jdbcType=CURSOR,javaType=java.sql.ResultSet,resultMap=aaDataMap})}
</select>
<resultMap type="com.bnymellon.pwb.pfdetails.domain.AccountActivity"
id="aaDataMap">
<result column="TICKER" property="ticker" jdbcType="VARCHAR" />
<result column="CUSIP" property="cusIp" jdbcType="VARCHAR" />
<result column="SECURITY_NAME" property="securityName"
jdbcType="VARCHAR"></result>
<result column="ASSET_CLASS" property="assetClass" jdbcType="VARCHAR" />
<result column="TRADE_DATE" property="tradeDate" jdbcType="DATE" />
<result column="SETTLE_DATE" property="settleDate" jdbcType="DATE" />
<result column="DESCRIPTION" property="description" jdbcType="VARCHAR" />
<result column="RECORD_TYPE" property="description" jdbcType="VARCHAR" />
<result column="ACCOUNT_NUMBER" property="accountNumber"
jdbcType="VARCHAR" />
<result column="QUANTITY" property="shares" jdbcType="VARCHAR" />
<result column="LONG_DESC" property="transDesc" jdbcType="VARCHAR" />
<result column="PORT_NUM" property="indicator" jdbcType="INTEGER" />
<result column="AMOUNT" property="amount" jdbcType="VARCHAR" />
</resultMap>
</mapper>
我使用 MyBatis 版本 3.0.4,我的 Oracle 驱动程序 jar 是 ojdbc14-10.2.0.3.0.jar
Procedure 的 IN 和 OUT 参数及其数据类型如下:
P_USER_INST NUMBER IN
P_GROUP_ID NUMBER IN
P_ENTITY_ID CHAR IN
P_ENTITY_NAME VARCHAR2 (30) IN
P_START_DATE DATE IN
P_END_DATE DATE IN
P_ASSETCLASS CHAR IN
P_TRAN_TYPE CHAR IN
P_PRIMARY_ASSET_ID VARCHAR2 IN
P_TICKER VARCHAR2 IN
P_ACCOUNT_DETAIL_CUR REF CURSOR OUT
我的 Java 中的 DTO 是下面(省略 setter/getter 方法)
private Integer userInstance;
private Integer accountGroupId;
private String accountId;
private Date startDate;
private Date endDate;
private String transactionType;
private String ticker;
private String cusipId;
private String assetClass;
private List<AccountActivity> domainList;
任何帮助都将受到高度赞赏,因为我不知道发生了什么并且真的陷入了困境。
When calling a Stored Procedure in Oracle returning refcursor I am getting an error
2011-05-10 03:36:23 DirtiesContextTestExecutionListener [DEBUG] After test method: context [[TestContext@3a363a36 testClass = AccountActivityServiceTest, locations = array<String>['classpath:/com/bnymellon/pwb/pfdetails/service/test/test-application-context.xml'], testInstance = com.bnymellon.pwb.pfdetails.service.test.AccountActivityServiceTest@6d2c6d2c, testMethod = getData@AccountActivityServiceTest, testException = org.springframework.jdbc.UncategorizedSQLException:
### Error updating database. Cause: java.sql.SQLException: ORA-08103: object no longer exists
### The error may involve com.bnymellon.pwb.pfdetails.persistence.AccountActivityMapper.getAccountActivityData-Inline
### The error occurred while setting parameters
### Cause: java.sql.SQLException: ORA-08103: object no longer exists
; uncategorized SQLException for SQL []; SQL state [72000]; error code [8103]; ORA-08103: object no longer exists
; nested exception is java.sql.SQLException: ORA-08103: object no longer exists
I am using Spring MyBatis integraton project. the version of MyBatis is 3.0.4
I can see the Procedure is being executed. The logs are below.
2011-05-10 03:36:16 PreparedStatement [DEBUG] ==> Executing: {call PWMWI.PAM_TRANSACTION_PKG.ACCOUNT_ACTIVITY( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)}
2011-05-10 03:36:16 PreparedStatement [DEBUG] ==> Parameters: 1987(Integer), 5627(Integer), null, null, 2010-01-01(Date), 2010-12-31(Date), All Asset Classes(String), [All, PYR](String), (String), null
My Mapper XMl is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bnymellon.pwb.pfdetails.persistence.AccountActivityMapper">
<select id="getAccountActivityData"
parameterType="com.bnymellon.pwb.pfdetails.common.AccountActivityDTO"
statementType="CALLABLE">
{call PWMWI.PAM_TRANSACTION_PKG.ACCOUNT_ACTIVITY(
#{userInstance,mode=IN, jdbcType=INTEGER},
#{accountGroupId,mode=IN,
jdbcType=INTEGER},
#{accountId,mode=IN, jdbcType=VARCHAR},
#{accountId,mode=IN, jdbcType=VARCHAR},
#{startDate,mode=IN,
jdbcType=DATE},
#{endDate,mode=IN, jdbcType=DATE},
#{assetClass,mode=IN, jdbcType=VARCHAR},
#{transactionType,mode=IN,
jdbcType=VARCHAR},
#{cusipId,mode=IN, jdbcType=VARCHAR},
#{ticker,mode=IN, jdbcType=VARCHAR},
#{domainList,mode=OUT,jdbcType=CURSOR,javaType=java.sql.ResultSet,resultMap=aaDataMap})}
</select>
<resultMap type="com.bnymellon.pwb.pfdetails.domain.AccountActivity"
id="aaDataMap">
<result column="TICKER" property="ticker" jdbcType="VARCHAR" />
<result column="CUSIP" property="cusIp" jdbcType="VARCHAR" />
<result column="SECURITY_NAME" property="securityName"
jdbcType="VARCHAR"></result>
<result column="ASSET_CLASS" property="assetClass" jdbcType="VARCHAR" />
<result column="TRADE_DATE" property="tradeDate" jdbcType="DATE" />
<result column="SETTLE_DATE" property="settleDate" jdbcType="DATE" />
<result column="DESCRIPTION" property="description" jdbcType="VARCHAR" />
<result column="RECORD_TYPE" property="description" jdbcType="VARCHAR" />
<result column="ACCOUNT_NUMBER" property="accountNumber"
jdbcType="VARCHAR" />
<result column="QUANTITY" property="shares" jdbcType="VARCHAR" />
<result column="LONG_DESC" property="transDesc" jdbcType="VARCHAR" />
<result column="PORT_NUM" property="indicator" jdbcType="INTEGER" />
<result column="AMOUNT" property="amount" jdbcType="VARCHAR" />
</resultMap>
</mapper>
I am using MyBatis version 3.0.4 and my Oracle driver jar is ojdbc14-10.2.0.3.0.jar
The IN and OUT parameters and their data types for Procedure are as below:
P_USER_INST NUMBER IN
P_GROUP_ID NUMBER IN
P_ENTITY_ID CHAR IN
P_ENTITY_NAME VARCHAR2 (30) IN
P_START_DATE DATE IN
P_END_DATE DATE IN
P_ASSETCLASS CHAR IN
P_TRAN_TYPE CHAR IN
P_PRIMARY_ASSET_ID VARCHAR2 IN
P_TICKER VARCHAR2 IN
P_ACCOUNT_DETAIL_CUR REF CURSOR OUT
My DTO in Java is below(omitting the setter/getter methods)
private Integer userInstance;
private Integer accountGroupId;
private String accountId;
private Date startDate;
private Date endDate;
private String transactionType;
private String ticker;
private String cusipId;
private String assetClass;
private List<AccountActivity> domainList;
Any help is highly appreciated as I am clue less what is going on and really stuck on this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我刚刚在 .net 而不是 Java 上遇到了类似的问题。
我的问题与游标基于全局临时表打开这一事实有关。当我们将 GTT 从“删除行”更改为“提交时保留行”时,它工作得很好。
看看这对你有用吗?
I've just had a similar issue with .net rather than Java.
my problem related to the fact that the cursor opened based on a global temporary table. when we changed the GTT to "on commit preserve rows" from "delete rows" it worked fine.
see if that works for you?
这可能是表或数据文件中的物理或逻辑损坏。
请咨询您的 DBA 以恢复数据。您可以在 http://24x7dba.blogspot.com/2011/08/salvage-data-from-corrupted-oracle.html
This can be a corruption, physical or logical, in a table or data file.
Check with your DBA for recovering the data. You can find steps on how to recover corrupted data from an Oracle table at http://24x7dba.blogspot.com/2011/08/salvage-data-from-corrupted-oracle.html
ORA-8103“对象不再存在”
错误:ORA 8103
文本:对象不再存在
原因:自操作开始以来,该对象已被另一个用户删除。
操作:删除对该对象的引用。
ORA-8103 报告 SQL 语句发现一个不再属于该语句中引用的对象的块。
原因
ORA-8103 是由无效的块类型引起的。块头具有无效的块类型或块内的块类型不是预期的;例如,需要一个数据块(Type=6)
但实际的块信息不是数据块(Type!=6)。
ORA-8103 也是由意外的 data_object_id 引起的,在执行受影响的 SQL 语句时,相关对象的 data_object_id 正在发生变化。
ORA-8103 "object no longer exists"
Error: ORA 8103
Text: object no longer exists
Cause: The object has been deleted by another user since the operation began.
Action: Remove references to the object.
ORA-8103 is reporting that a SQL statement found a block that no longer belongs to the object referenced in the statement.
Cause
ORA-8103 is caused by an invalid block type. The block header has an invalid block type or the block type inside the block is not expected; e.g. a data block (Type=6) was expected
but the actual block information is not a data block (Type!=6).
ORA-8103 is also caused by an unexpected data_object_id where it is changing for the involved objects while the affected SQL statement is executed.
经过一周的努力,我终于解决了这个问题:
解决方案:很可能是基于全局临时表(GTT)打开游标,该表是使用 ON COMMIT DELETE ROWS 选项创建的。 ORA-08103:对象不再存在错误的原因是删除语句后紧跟的提交语句。 DBA团队不同意改变GTT
由于提交时保留行,所以最后我在 Java 服务层中添加了代码库[实现 Spring - 编程事务]
After Struggling one week finally I fixed the Issue:
Solution: Most likely that a cursor is opened based on a global temporary table(GTT), which had been created with ON COMMIT DELETE ROWS option. And the cause of the ORA-08103: object no longer exists error is commit statement that followed right after the delete statement. DBA team didn't agree to change the GTT
as on commit preserve rows so finally I added code base in Java Service Layer[Implementing the Spring - Programmatic Transaction]
就我而言,此错误与全局临时表有关。
在表DDL中,我从“提交时删除行”更改为“提交时保留行”,问题已得到解决。
In my case, this error was related to a global temporary table.
In the table DDL, I changed from "on commit delete rows" to "on commit preserve rows" and the problem has been fixed.
创建全局临时表时,如下所示创建它。
创建全局临时表 table_name(col-1 类型, col-2 类型, ...) ON COMMIT PRESERVE ROWS
Create your global temporary table as below when you are creating it.
CREATE GLOBAL TEMPORARY TABLE table_name(col-1 type, col-2 type, ...) ON COMMIT PRESERVE ROWS