Spring

[Spring Batch] ORA-00955 에러 해결하기

천방지축 개발노트 2024. 12. 12. 19:37

Spring Batch의 초기 구성을 설정하는 과정에서 여러 오류가 발생할 수 있다.

이전 글에 이어 발생할 수 있는 ORA-0085 에러에 대해 알아보자.


 

SQLSyntaxErrorException: ORA-00955: 기존의 객체가 이름을 사용하고 있습니다.

table already exists

Caused by: org.springframework.jdbc.datasource.init.ScriptStatementFailedException: 
Failed to execute SQL script statement #1 of class path resource [org/springframework/batch/core/schema-oracle10g.sql]: 
CREATE TABLE BATCH_JOB_INSTANCE ( JOB_INSTANCE_ID NUMBER(19,0) NOT NULL PRIMARY KEY , VERSION NUMBER(19,0) , JOB_NAME VARCHAR2(100 char) NOT NULL, JOB_KEY VARCHAR2(32 char) NOT NULL, constraint JOB_INST_UN unique (JOB_NAME, JOB_KEY) ) ; 
nested exception is java.sql.SQLSyntaxErrorException: ORA-00955: 기존의 객체가 이름을 사용하고 있습니다.

Batch 애플리케이션을 재기동하니 위 에러가 발생했다. 찾아보니 이전에 메타 테이블을 초기화시키기 위해 설정했었던 속성이 문제의 원인이었다.

spring.batch.job.initialize-schema=always
spring.sql.init.mode=always

유사한 성격의 위 두 속성들의 'ALWAYS' 값은 애플리케이션이 시작될 때마다 초기화 스크립트의 실행을 강제하는데, 이 경우 이미 존재하는 테이블을 다시 생성(CREATE TABLE) 하려고 시도하면서 충돌이 발생할 수 있다.

 

 

테이블 생성시 발생하는 충돌 문제 해결 방법

1) DDL 스크립트 실행과 관련한 속성(spring.sql.init.mode 등) 삭제.

 

2) 이미 생성된 테이블을 덮어쓰려는 시도가 없도록 'always' 대신 'never'로 옵션 값 재설정. 추가적으로 배포 환경(개발, 테스트, 운영) 별로 서로 다른 설정을 사용하는 것이 좋다.

spring:
  profiles: dev
  sql:
    init:
      mode: always
---
spring:
  profiles: prod
  sql:
    init:
      mode: never

 

3) 사용하는 DB가 오라클(Oracle)이 아니라면 'CREATE TABLE IF NOT EXISTS' 구문으로 메타 테이블 초기화를 위한 스크립트를 수정.

 

4) 배치와 관련한 메타 테이블을 전부 삭제 후 재기동. 메타 테이블 삭제 시에는 DROP TABLE ... CASCADE CONSTRAINTS 명령어를 사용하여 참조 무결성 제약 조건도 함께 제거해야 한다는 점을 주의해야한다.

DROP TABLE BATCH_JOB_EXECUTION CASCADE CONSTRAINTS;