My Environment:
- Java 8
- MyBatis 3.5.6
- SAP jConnect for JDBC 16.0 SP04 (note: 16.0 SP04 is now JDBC4.2 compliant)
I have a problem on LocalDateTimeHandler
with SAP jConnect.
Executing a SELECT statement for a DATETIME
column with mapping to a LocalDateTime
property causes a SQLException (caused by ClassCastException).
Caused by: java.lang.ClassCastException: Cannot cast com.sybase.jdbc42.tds.SybTimestamp to java.time.LocalDateTime
at java.lang.Class.cast(Class.java:3369)
at com.sybase.jdbc42.jdbc.SybResultSet.convertObjectToJavaType(SybResultSet.java:3665)
at com.sybase.jdbc42.jdbc.SybResultSet.getObject(SybResultSet.java:3632)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.ibatis.logging.jdbc.ResultSetLogger.invoke(ResultSetLogger.java:69)
at com.sun.proxy.$Proxy211.getObject(Unknown Source)
at org.apache.ibatis.type.LocalDateTimeTypeHandler.getNullableResult(LocalDateTimeTypeHandler.java:38)
at org.apache.ibatis.type.LocalDateTimeTypeHandler.getNullableResult(LocalDateTimeTypeHandler.java:28)
at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:85)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getPropertyMappingValue(DefaultResultSetHandler.java:511)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.applyPropertyMappings(DefaultResultSetHandler.java:480)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getRowValue(DefaultResultSetHandler.java:404)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValuesForSimpleResultMap(DefaultResultSetHandler.java:354)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValues(DefaultResultSetHandler.java:328)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSet(DefaultResultSetHandler.java:301)
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSets(DefaultResultSetHandler.java:194)
at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:65)
at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:79)
at org.apache.ibatis.executor.ReuseExecutor.doQuery(ReuseExecutor.java:60)
at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:325)
at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:109)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:89)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:427)
... 54 more
The MyBatis LocalDateTimeTypeHandler expects ResultSet.getObject() to return a LocalDateTime
object, but jConnect doesn't support it.
According to the javadoc and JDBC 4.2 specification for the TIMESTAMP
column,
only java.sql.Timestamp
type conversion must be supported at a minimum, but other type conversions (including LocalDateTime
) are not expected to be supported by some vendors.
My Questions:
- Is this a bug of MyBatis ? or by design to support only some specific vendors ?
- Is there any workaround ?
Reference
- javadoc: https://docs.oracle.com/javase/8/docs/api/java/sql/ResultSet.html#getObject-java.lang.String-java.lang.Class-
- JDBC API Spec 4.2: https://download.oracle.com/otndocs/jcp/jdbc-4_2-mrel2-spec/index.html
- TABLE B-3 Mapping from JDBC Types to Java Object Types