简体   繁体   English

ORA-08103:对象不再存在:Oracle 过程从 MyBatis 返回 Refcursor 时发生此错误

[英]ORA-08103: object no longer exists: This error is occuring for Oracle Procedure returning Refcursor from MyBatis

When calling a Stored Procedure in Oracle returning refcursor I am getting an error在 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 

I am using Spring MyBatis integraton project.我正在使用 Spring MyBatis 集成项目。 the version of MyBatis is 3.0.4 MyBatis 的版​​本是 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 如下:

<?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我使用的是 MyBatis 3.0.4 版,我的 Oracle 驱动程序 jar 是 ojdbc14-10.2.0.3.0.jar

The IN and OUT parameters and their data types for Procedure are as below: 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    

My DTO in Java is below(omitting the setter/getter methods)我在 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;

Any help is highly appreciated as I am clue less what is going on and really stuck on this.任何帮助都受到高度赞赏,因为我不知道发生了什么并且真的坚持这一点。

I've just had a similar issue with .net rather than Java.我刚刚在 .net 而不是 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.当我们将 GTT 从“删除行”更改为“提交时保留行”时,它运行良好。

see if that works for you?看看这对你有用吗?

ORA-8103 "object no longer exists" ORA-8103 "对象不再存在"

Error: ORA 8103错误: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. ORA-8103 报告 SQL 语句发现一个块不再属于该语句中引用的对象。 Cause ORA-8103 is caused by an invalid block type.原因 ORA-8103 是由无效的块类型引起的。 The block header has an invalid block type or the block type inside the block is not expected;区块头的区块类型无效或区块内的区块类型不是预期的; eg a data block (Type=6) was expected but the actual block information is not a data block (Type!=6).例如,一个数据块(类型= 6)是预期的,但实际的块信息不是数据块(类型!= 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. ORA-8103 也是由意外的 data_object_id 引起的,在执行受影响的 SQL 语句时,它正在更改相关对象。

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.解决方案:很可能是基于全局临时表 (GTT) 打开了游标,该表已使用 ON COMMIT DELETE ROWS 选项创建。 And the cause of the ORA-08103: object no longer exists error is commit statement that followed right after the delete statement. ORA-08103:对象不再存在错误的原因是在删除语句之后紧跟的提交语句。 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] DBA 团队不同意在提交保留行时更改 GTT,所以最后我在 Java 服务层中添加了代码库[实现 Spring - 程序化事务]

package com.test;

import java.util.List;
import javax.sql.DataSource;

import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

public class StudentJDBCTemplate implements StudentDAO {
   private DataSource dataSource;
   private JdbcTemplate jdbcTemplateObject;
   private PlatformTransactionManager transactionManager;

   public void setDataSource(DataSource dataSource) {
      this.dataSource = dataSource;
      this.jdbcTemplateObject = new JdbcTemplate(dataSource);
   }
   public void setTransactionManager(PlatformTransactionManager transactionManager) {
      this.transactionManager = transactionManager;
   }
   public void create(String name, Integer age, Integer marks, Integer year){
      TransactionDefinition def = new DefaultTransactionDefinition();
      TransactionStatus status = transactionManager.getTransaction(def);

      try {
         String SQL1 = "insert into Student (name, age) values (?, ?)";
         jdbcTemplateObject.update( SQL1, name, age);

         // Get the latest student id to be used in Marks table
         String SQL2 = "select max(id) from Student";
         int sid = jdbcTemplateObject.queryForInt( SQL2 );

         String SQL3 = "insert into Marks(sid, marks, year) " + "values (?, ?, ?)";
         jdbcTemplateObject.update( SQL3, sid, marks, year);

         System.out.println("Created Name = " + name + ", Age = " + age);
         transactionManager.commit(status);
      } 
      catch (DataAccessException e) {
         System.out.println("Error in creating record, rolling back");
         transactionManager.rollback(status);
         throw e;
      }
      return;
   }
   public List<StudentMarks> listStudents() {
      String SQL = "select * from Student, Marks where Student.id=Marks.sid";
      List <StudentMarks> studentMarks = jdbcTemplateObject.query(SQL, 
         new StudentMarksMapper());

      return studentMarks;
   }
}

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.在表 DDL 中,我从“提交时删除行”更改为“提交时保留行”,问题已解决。

创建全局临时表时,如下所示。

CREATE GLOBAL TEMPORARY TABLE table_name(col-1 type, col-2 type, ...) ON COMMIT PRESERVE ROWS

This can be a corruption, physical or logical, in a table or data file.这可能是表或数据文件中的物理或逻辑损坏。 Check with your DBA for recovering the data.请咨询您的 DBA 以恢复数据。 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您可以在http://24x7dba.blogspot.com/2011/08/salvage-data-from-corrupted-oracle.html找到有关如何从 Oracle 表中恢复损坏数据的步骤

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Java.sql.SQLException:ORA-08103:对象在存储过程中不再存在游标 - Java.sql.SQLException: ORA-08103: object no longer exists cursor in stored procedure 获取SQL异常ORA-08103:Java中不再存在对象 - Getting SQL Exception ORA-08103: object no longer exists in java java.sql.SQLException:ORA-08103:Java中不再存在对象 - java.sql.SQLException: ORA-08103: object no longer exists in java 如何使用Eclipselink 2.4运行Oracle PROCEDURE,返回SYS_REFCURSOR - How to run a Oracle PROCEDURE with Eclipselink 2.4 Returning a SYS_REFCURSOR Oracle JDBC从过程获取SYS_REFCURSOR - Oracle JDBC Get SYS_REFCURSOR from procedure Mybatis-从SELECT返回包含Hashmap的对象 - Mybatis - Returning Object containing Hashmap from SELECT 无法从mybatis执行的oracle过程中接收参数 - cannot receive out parameter from oracle procedure executed by mybatis Which is better for selecting among these 1.sys_refcursor 2. custom JSON 3.custom object/record type from Oracle 12c plsql procedure, Java 8? - Which is better for selecting among these 1.sys_refcursor 2. custom JSON 3.custom object/record type from Oracle 12c plsql procedure, Java 8? MyBatis Springs Oracle存储过程 - MyBatis Springs Oracle Stored Procedure 从Oracle存储过程中的SYS_REFCURSOR读取数据并在java中重用它 - read data from SYS_REFCURSOR in a Oracle stored procedure and reuse it in java
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM