[Project]/업무일지

java.text.ParseException: Unparseable date, SQLSyntaxErrorException: ORA-00947

soheepark 2024. 7. 3. 14:38
728x90
반응형

[현상황]

  • 웹 개발이 아닌, 자바 어플리케이션 개발 (Java Swing, Java)
  • DB : Oracle 11g
  • JAVA : JDK 1.8
  • Java Swing을 이용한 MVC 구조 (DTO, DAO, BIZ)

 

View단에서 날짜 데이터를 변경하여 저장을 클릭하면 다음과 같은 문제가 발생했다.

  • 'yyyymmdd'가 아닌 'yy/mm/dd' 형식으로 날짜 데이터 저장
  • 날짜 데이터가 존재하는 A의 정보를 화면에 표시 후, 날짜 데이터가 NULL인 B의 정보를 표시하는 화면을 띄우면 A의 날짜 정보가 그대로 표시되는 문제 발생
  • 날짜 데이터의 첫번째 수정만 반영되고 두번째 수정서부터는 반영되지 않음

View.java 파일은 문제가 없는 것 같고,

건드려야 할 파일이 있다면 xml과 서비스단 로직 파일인 것 같다.


1. ParseException 처리 01

1-1. 원인

날짜 데이터를 변경하여 저장했을 때 DB에 '20240703'과 같은 yyyymmdd 형식으로 저장되어야 하는 상황이다.

그러나 현재 '24/07/03'과 같은 yy/mm/dd 형식으로 저장되는 문제점이 발생했다.

 

<에러 메시지 01>

java.text.ParseException: Unparseable date: "24/07/03"

 

이는 첫번째로 서비스 로직.java 파일에서도 처리해야 하는 부분인 것 같다.

이 중 데이터를 수정하여 저장하는 로직을 가지고 있는 메소드 savedata()에서 코드를 잘못 작성한 부분이 있었다.

private void savedata() {
		try {
		savedataDTO.setDate(common.datetype02.format(view.date.getDate()));
		} catch (NumberFormatException e) {
	}

이때 common 파일은 공통으로 설정할 수 있는 변수 등을 모아놓은 파일이다.

 

common 파일의 공통 변수인 데이터포맷을 선택하여 끌어와 date에 적용시키면 된다.

 

그런데 하필 내가 끌어온 datetype02는 날짜 형식이 'yyyy-mm-dd'였다.

내가 잘못 끌어와서 해당 에러가 난 것이 아닌가 싶어서 정확히 일치하는 포맷을 찾아 변경하려고 한다.

 

일치하는 포맷은 'yyyymmdd' 형식의 datetype01이다.

 

1-2. 해결

private void savedata() {
		try {
		savedataDTO.setDate(common.datetype01.format(view.date.getDate()));
		} catch (NumberFormatException e) {
	}

common 파일의 공통 변수인 datetype01을 끌어와 date에 적용시킨다.

 

위 코드에 해당하는 common 파일 중 일부 내용은 다음과 같다.

public static dateformat datetype01 = new dateformat("yyyyMMdd");

 

날짜 데이터를 저장할 때의 형식을 변경하여 지정 완료하였다.

 

2. ParseException 처리 02

2-1. 원인

View단에서 날짜 데이터를 수정하고 저장하는 과정에서 코드를 수정해도

날짜 데이터가 저장되는 형식이 'yy/mm/dd'로 나타났다.

 

xml 파일을 살펴보다 데이터 수정 영역과 관련된 부분에서 특이점을 발견했다.

<update id="update" parameterClass="dto.dataDTO">
		UPDATE 테이블명
        /* 생략 */
		   <isNotNull prepend="," property="AS명">
				컬럼명 = TO_DATE(#컬럼명#,'YYYY-MM-DD') /* 수정 필요한 코드 */
			</isNotNull>
        /* 생략 */
</update>

날짜 데이터를 수정하고 저장 명령을 내리는 SQL문에서,

date 형식으로 바꿔서 저장하라는 명령을 작성한 게 원인이 되어 이상하게 저장되는게 아닌가 싶다.

 

2-2. 해결

해당 코드를 date 형식으로 저장하지 않고 string 형식으로 저장하도록 변경하겠다.

참고로 DTO와 컬럼 타입 모두 String 형식으로 되어 있었다.

<update id="update" parameterClass="dto.dataDTO">
		UPDATE 테이블명
        /* 생략 */
		   <isNotNull prepend="," property="AS명">
				컬럼명 = #컬럼명#		 /* 수정 완료 */
			</isNotNull>
        /* 생략 */
</update>

 

그러나 해당 코드 변경을 완료하고 코드를 실행하여

View단에서 날짜 데이터를 수정하고 저장하는 과정에서 다음과 같은 에러가 발생했다.

 

3. SQLSyntaxErrorException 처리

3-1. 원인

원인은 SQL문에서 문법 오류가 있었다는 것이다.

 

<에러 메시지 03>

 StackTrace  : com.ibatis.common.jdbc.exception.NestedSQLException:   
--- The error occurred while applying a parameter map.  
--- Check the <namespace명>.<id명>-InlineParameterMap.  
--- Check the statement (update failed).  
--- Cause: java.sql.SQLSyntaxErrorException: ORA-00947: not enough values

정확히는 xml 파일에서 작성하는 SQL문 중 '값'에 해당하는 코드를 덜 작성했다는 것이다.

 

실제로 에러 메시지에 표시된 id값에 해당하는 SQL문 중에서

values 값을 까먹고 작성하지 않은 것이 발견되었다.

<insert id="insertData" parameterClass="dto.DataDTO">
	insert into 테이블명(
		<isNotEmpty prepend="," property="AS명"> 
			컬럼명
		</isNotEmpty>
	) values (
    	/* 이 부분에서 작성되었어야 할 코드가 없었음 */
        )
</insert>

 

3-2. 해결

그래서 빼먹고 작성하지 않은 코드를 해당 영역에 추가해주었다.

<insert id="insertData" parameterClass="dto.DataDTO">
	insert into 테이블명(
		<isNotEmpty prepend="," property="AS명"> 
			컬럼명
		</isNotEmpty>
	) values (
		<isNotEmpty prepend="," property="AS명"> /* 추가 완료 */
			#컬럼명#
		</isNotEmpty>
        )
</insert>

 

위와 같이 코드를 변경하였더니 날짜 데이터를 변경하여 저장했을 때

DB에 'yyyymmdd' 형식으로 데이터가 저장되었다.


  • 'yyyymmdd'가 아닌 'yy/mm/dd' 형식으로 날짜 데이터 저장
  • 날짜 데이터가 존재하는 A의 정보를 화면에 표시 후, 날짜 데이터가 NULL인 B의 정보를 표시하는 화면을 띄우면 A의 날짜 정보가 그대로 표시되는 문제 발생
  • 날짜 데이터의 첫번째 수정만 반영되고 두번째 수정서부터는 반영되지 않음

결과적으로 해당 문제들이 모두 해결되었다.

 

728x90
반응형