Error: Mybatis 노답에러 – java.sql.SQLException: 부적합한 열 유형

Error

ERROR jdbc.sqltiming – 11. CallableStatement.setNull(110, 1111)
java.sql.SQLException: 부적합한 열 유형

에러발생 상황 기록

Spring Mybatis를 이용해서
파라미터가 200개 가량 있는 Oracle의 PL/SQL구문을 호출하는 상황

손으로 하나하나 쓰기 귀찮아서 DTO의 필드를 잘라붙여서 PL/SQL 구문을 호출했더니 해당 오류가 발생했다.

에러 메세지도 애매하게 어디서 오류가 났는지 정확히 짚어주지 못하고 해서…
노가다로 디버깅을 시작…

해결

필드 이름이 잘못 들어갔을거라고 생각을 했기에 먼저 디비에 접속해서 
PL/SQL 구문을 확인하고 돌아가는 것을 확인했다.

그리고 DTO에서 필드를 20개단위로 붙여넣어가며 확인을 했다.

그 결과~

이 프로젝트에는 lombok을 이용하고 있었는데 mybatis가 getter, setter를 이용해서 DTO에 접근하다 보니 내가 생각했던 것과 좀 다른형태로 이름이 변환되고 있었고 거기서 문제가 발생했다.

mHash : 2글자째 대문자가 오는 상황
Cash : 1글자가 대문자인 상황

ex)

mhash  getMhash()
mHash getMHash()
cash getCash()
Cash getCash()??

이렇게 자동변환이 좀 애매한 상황이 생기는 경우가 있다. 이런부분을 확인해서 수정 해 주고서야 제대로 동작하는 것을 볼 수 있었다.

Mybatis – Oracle Procedure 연동해서 사용해서 여러개의 ResultSet을 받아오는 케이스

인터넷에 한개짜리는 많이 나오는데

여러개를 받아야 하는 경우에 대한 케이스.
한참 디버깅해서 알아냈지만
알고보면 간단하다

 

솔루션부터… Mybatis Mapper파일
매퍼를 여러개 지정 해 줘야한다. 한곳에서 result가 다 담겨나오지 않네.. 생각해보면 당연한데

<mapper namespace="org.beansugar.api.server.module.common.dao.CommonMainDAO">
	<resultMap type="java.util.HashMap" id="pMap">
	</resultMap>
	<resultMap type="java.util.HashMap" id="pMap0">
	</resultMap>
	<resultMap type="java.util.HashMap" id="pMap1">
	</resultMap>
	<resultMap type="java.util.HashMap" id="pMap2">
	</resultMap>
	<resultMap type="java.util.HashMap" id="pMap3">
	</resultMap>
	<resultMap type="java.util.HashMap" id="pMap4">
	</resultMap>
	<resultMap type="java.util.HashMap" id="pMap5">
	</resultMap>
	<resultMap type="java.util.HashMap" id="pMap6">
	</resultMap>
	<resultMap type="java.util.HashMap" id="pMap7">
	</resultMap>
</mapper>

 

또 Mybatis Mapper파일이지만 이번엔 프로시저 호출부분

	<select id="PID-057" parameterType="hashmap" statementType="CALLABLE">
		{ call MEMBER_001(
			#{username,mode=IN,jdbcType=VARCHAR},

			#{email,mode=OUT,jdbcType=VARCHAR},
			#{joinDate,mode=OUT,jdbcType=VARCHAR},
			#{name,mode=OUT,jdbcType=VARCHAR},


			#{groupInfo,mode=OUT,jdbcType=CURSOR, javaType=java.sql.ResultSet, resultMap=pMap0},
			#{friendInfo,mode=OUT,jdbcType=CURSOR, javaType=java.sql.ResultSet, resultMap=pMap1},
			#{pointInfo,mode=OUT,jdbcType=CURSOR, javaType=java.sql.ResultSet, resultMap=pMap2},

			#{code,mode=OUT,jdbcType=VARCHAR},
			#{message,mode=OUT,jdbcType=VARCHAR}
			)
		}
	</select>

 

Java – Mybatis 호출 코드

getSqlSessionTemplate().selectOne("procedure-member-001", param);

List<Map<String,Object>> subList0 = (List<Map<String, Object>>)param.get("groupInfo");

subList0내의 결과값은 프로시저에서 지정한 이름으로 나온다. mybatis에서 손대려면 resultMap을 만져주면 될 것 같은데...
그것도 귀찮으니 그냥 코드로 하는게 나을 것같다