ORA-08103: объект больше не существует: эта ошибка возникает для процедуры Oracle, возвращающей Refcursor из MyBatis

При вызове хранимой процедуры в 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

Я вижу, что Процедура выполняется. Логи ниже.

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, а файл jar драйвера Oracle — ojdbc14-10.2.0.3.0.jar.

Параметры 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    

Мой DTO в Java ниже (без методов установки/получения)

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;

Любая помощь высоко ценится, так как я не знаю, что происходит, и действительно застрял в этом.


person chotachetan    schedule 11.05.2011    source источник


Ответы (6)


У меня только что была аналогичная проблема с .net, а не с Java.

моя проблема связана с тем, что курсор открывался на основе глобальной временной таблицы. когда мы изменили GTT на «при фиксации сохранить строки» с «удалить строки», он работал нормально.

посмотрите, работает ли это для вас?

person Andrew    schedule 15.06.2011
comment
Я забыл установить для autocommit значение false, когда я изменил эту конфигурацию, все заработало нормально. - person nMoncho; 12.10.2013

Это может быть повреждение, физическое или логическое, в таблице или файле данных. Обратитесь к своему администратору баз данных для восстановления данных. Инструкции по восстановлению поврежденных данных из таблицы Oracle можно найти по адресу http://24x7dba.blogspot.com/2011/08/salvage-data-from-corrupted-oracle.html

person george    schedule 02.08.2011
comment
Хотя эта ссылка может ответить на вопрос, лучше включить сюда основные части ответа и предоставить ссылку для справки. Ответы, содержащие только ссылки, могут стать недействительными, если связанная страница изменится. - person Qantas 94 Heavy; 28.11.2013

ORA-8103 "объект больше не существует"

Ошибка: ORA 8103

Текст: объект больше не существует

Причина: Объект был удален другим пользователем после начала операции. Действие: Удалите ссылки на объект.

ORA-8103 сообщает, что оператор SQL обнаружил блок, который больше не принадлежит объекту, указанному в операторе. Причина ORA-8103 вызван недопустимым типом блока. Заголовок блока имеет недопустимый тип блока или тип блока внутри блока не ожидается; например ожидался блок данных (тип = 6), но фактическая информация о блоке не является блоком данных (тип! = 6). ORA-8103 также вызван непредвиденным data_object_id, когда он изменяется для задействованных объектов во время выполнения затронутого оператора SQL.

person ParnassusData    schedule 22.02.2016

После борьбы в течение одной недели, наконец, я решил проблему:

Решение: Скорее всего, курсор открывается на основе глобальной временной таблицы (GTT), которая была создана с опцией ON COMMIT DELETE ROWS. И причиной ошибки ORA-08103: объект больше не существует является оператор фиксации, который следует сразу после оператора удаления. Команда администраторов баз данных не согласилась изменить 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;
   }
}
person user1765387    schedule 16.11.2017

В моем случае эта ошибка была связана с глобальной временной таблицей. В таблице DDL я изменил «при фиксации строк удаления» на «при фиксации строк сохранения», и проблема была исправлена.

person Genivan    schedule 25.09.2019

Создайте свою глобальную временную таблицу, как показано ниже, при ее создании.

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

person CRV    schedule 27.02.2020