[Request processing failed: org.mybatis.spring.MyBatisSystemException] with root cause
java.sql.SQLException: 부적합한 열 유형: getBLOB not implemented for class oracle.jdbc.driver.T4CLongRawAccessor
at oracle.jdbc.driver.GeneratedAccessor.getBLOB(GeneratedAccessor.java:1021) ~[ojdbc8-21.9.0.0.jar:21.9.0.0.0]
at oracle.jdbc.driver.GeneratedStatement.getBLOB(GeneratedStatement.java:289) ~[ojdbc8-21.9.0.0.jar:21.9.0.0.0]
at oracle.jdbc.driver.GeneratedScrollableResultSet.getBLOB(GeneratedScrollableResultSet.java:547) ~[ojdbc8-21.9.0.0.jar:21.9.0.0.0]
at oracle.jdbc.driver.GeneratedScrollableResultSet.getBlob(GeneratedScrollableResultSet.java:136) ~[ojdbc8-21.9.0.0.jar:21.9.0.0.0]
at oracle.jdbc.driver.GeneratedResultSet.getBlob(GeneratedResultSet.java:585) ~[ojdbc8-21.9.0.0.jar:21.9.0.0.0]
at com.zaxxer.hikari.pool.HikariProxyResultSet.getBlob(HikariProxyResultSet.java) ~[HikariCP-5.1.0.jar:na]
at org.apache.ibatis.type.BlobTypeHandler.getNullableResult(BlobTypeHandler.java:39) ~[mybatis-3.5.14.jar:3.5.14]
at org.apache.ibatis.type.BlobTypeHandler.getNullableResult(BlobTypeHandler.java:28) ~[mybatis-3.5.14.jar:3.5.14]
at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:86) ~[mybatis-3.5.14.jar:3.5.14]
at org.apache.ibatis.type.UnknownTypeHandler.getNullableResult(UnknownTypeHandler.java:77) ~[mybatis-3.5.14.jar:3.5.14]
at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:86) ~[mybatis-3.5.14.jar:3.5.14]
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getPropertyMappingValue(DefaultResultSetHandler.java:530) ~[mybatis-3.5.14.jar:3.5.14]
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.applyPropertyMappings(DefaultResultSetHandler.java:495) ~[mybatis-3.5.14.jar:3.5.14]
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getRowValue(DefaultResultSetHandler.java:418) ~[mybatis-3.5.14.jar:3.5.14]
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValuesForSimpleResultMap(DefaultResultSetHandler.java:366) ~[mybatis-3.5.14.jar:3.5.14]
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValues(DefaultResultSetHandler.java:337) ~[mybatis-3.5.14.jar:3.5.14]
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSet(DefaultResultSetHandler.java:310) ~[mybatis-3.5.14.jar:3.5.14]
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSets(DefaultResultSetHandler.java:202) ~[mybatis-3.5.14.jar:3.5.14]
at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:66) ~[mybatis-3.5.14.jar:3.5.14]
at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:80) ~[mybatis-3.5.14.jar:3.5.14]
at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:65) ~[mybatis-3.5.14.jar:3.5.14]
at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:336) ~[mybatis-3.5.14.jar:3.5.14]
at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:158) ~[mybatis-3.5.14.jar:3.5.14]
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:110) ~[mybatis-3.5.14.jar:3.5.14]
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:90) ~[mybatis-3.5.14.jar:3.5.14]
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:154) ~[mybatis-3.5.14.jar:3.5.14]
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) ~[mybatis-3.5.14.jar:3.5.14]
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:142) ~[mybatis-3.5.14.jar:3.5.14]
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:75) ~[mybatis-3.5.14.jar:3.5.14]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:569) ~[na:na]
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:425) ~[mybatis-spring-3.0.3.jar:3.0.3]
at jdk.proxy2/jdk.proxy2.$Proxy63.selectOne(Unknown Source) ~[na:na]
at org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:160) ~[mybatis-spring-3.0.3.jar:3.0.3]
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:87) ~[mybatis-3.5.14.jar:3.5.14]
at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:141) ~[mybatis-3.5.14.jar:3.5.14]
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) ~[mybatis-3.5.14.jar:3.5.14]
mybatis 이용하여 oracle database
테이블에 데이터를 조회하는 기능을 개발하는 중에
이미지 파일들이 있는 long row 컬럼이 있었는데
단순하게 resultMap을 사용하여
jdbcType을 LONGVARBINARY 로 선언하면 처리가 가능할 줄 알았으나
jdbcType은insert나 update 같은 쿼리를 수행할 때는 MyBatis가 파라미터 타입을 명확히 인식할 수 있도록 jdbcType을 지정하는 경우 사용하는 것이니 나처럼 바보같은 실수는 하지 않길 바란다.. 😁
속성 | 설명 | |
property | 결과 칼럼에 매핑하기 위한 필드나 프로퍼티. 자바빈 프로퍼티가 해당 이름과 일치한다면 그 프로퍼티가 사용될 것이다. 반면에 마이바티스는 해당 이름이 필드를 찾을 것이다. 점 표기를 사용하여 복잡한 프로퍼티 검색을 사용할 수 있다. 예를들어 “username”과 같이 간단하게 매핑될 수 있거나 “address.street.number” 처럼 복잡하게 매핑될수도 있다. | |
column | 데이터베이스의 칼럼명이나 별칭된 칼럼 라벨. resultSet.getString(columnName) 에 전달되는 같은 문자열이다. | |
javaType | 패키지 경로를 포함한 클래스 전체명이거나 타입 별칭. 자바빈을 사용한다면 마이바티스는 타입을 찾아낼 수 있다. 반면에 HashMap으로 매핑한다면 기대하는 처리를 명확히 하기 위해 javaType 을 명시해야 한다. | |
jdbcType | 지원되는 타입 목록에서 설명하는 JDBC 타입. JDBC타입은 insert, update 또는 delete 하는 null 입력이 가능한 칼럼에서만 필요하다. JDBC의 요구사항이지 마이바티스의 요구사항이 아니다. JDBC로 직접 코딩을 하다보면 null이 가능한 값에 이 타입을 지정할 필요가 있을 것이다. | |
typeHandler | 이 문서 앞에서 이미 타입 핸들러에 대해 설명했다. 이 프로퍼티를 사용하면 디폴트 타입 핸들러를 오버라이드 할 수 있다. 이 값은 TypeHandler구현체의 패키지를 포함한 전체 클래스명이나 타입별칭이다. |
그렇다면 long raw에 값을 어떻게 해야 잘 처리 할 수 있을까?
resultMap에서 아래 세가지 방법으로 처리 할 수 있다.
1. javaType을 byte[] 로 받는 방법
2. javaType을 String으로 받는 방법
3. typeHandler를 사용하는 방법
나는 로직을 한 곳에 집중 시키는 것을 좋아해서 3번을 추천한다.
그렇다면 typeHandler 는 어떻게 코드를 작성해야 할까?
아래는 long raw 값을 자바에서 받기 위한 typehandler 예시 코드이다.
package com.xxx.xxx.handler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class LongRawHandler implements TypeHandler<byte[]> {
@Override
public void setParameter(PreparedStatement ps, int i, byte[] parameter, JdbcType jdbcType) throws SQLException {
if (parameter != null) {
ps.setBytes(i, parameter);
} else {
ps.setNull(i, java.sql.Types.LONGVARBINARY);
}
}
@Override
public byte[] getResult(ResultSet rs, String columnName) throws SQLException {
return rs.getBytes(columnName);
}
@Override
public byte[] getResult(ResultSet rs, int columnIndex) throws SQLException {
return rs.getBytes(columnIndex);
}
@Override
public byte[] getResult(CallableStatement cs, int columnIndex) throws SQLException {
return cs.getBytes(columnIndex);
}
}
해당 오류 덕분에 mybatis에 대해 더 자세히 알게 된 것 같다 :)
Ref.
https://mybatis.org/mybatis-3/ko/index.html
https://mybatis.org/mybatis-3/ko/sqlmap-xml.html
반응형