【问题标题】:Mybatis not handling ZonedDateTimeMybatis 不处理 ZonedDateTime
【发布时间】:2022-06-24 19:19:14
【问题描述】:

我在 DATE 类型的数据库表中有列,我希望 mybatis 将其转换为 ZonedDateTime,但似乎内置的 ZonedDateTimeHandler 不起作用。我得到以下异常

Caused by: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'UPDATED_DATE' from result set.  Cause: java.sql.SQLSyntaxErrorException: incompatible data type in conversion
    at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:87)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createUsingConstructor(DefaultResultSetHandler.java:711)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createByConstructorSignature(DefaultResultSetHandler.java:694)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createResultObject(DefaultResultSetHandler.java:658)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.createResultObject(DefaultResultSetHandler.java:631)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getRowValue(DefaultResultSetHandler.java:398)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValuesForSimpleResultMap(DefaultResultSetHandler.java:355)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleRowValues(DefaultResultSetHandler.java:329)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSet(DefaultResultSetHandler.java:302)
    at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSets(DefaultResultSetHandler.java:195)
    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.SimpleExecutor.doQuery(SimpleExecutor.java:63)
    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:151)
    ... 36 common frames omitted
Caused by: java.sql.SQLSyntaxErrorException: incompatible data type in conversion
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCResultSet.getObject(Unknown Source)
    at org.hsqldb.jdbc.JDBCResultSet.getObject(Unknown Source)
    at com.zaxxer.hikari.pool.HikariProxyResultSet.getObject(HikariProxyResultSet.java)
    at org.apache.ibatis.type.ZonedDateTimeTypeHandler.getNullableResult(ZonedDateTimeTypeHandler.java:38)
    at org.apache.ibatis.type.ZonedDateTimeTypeHandler.getNullableResult(ZonedDateTimeTypeHandler.java:28)
    at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:85)
    ... 53 common frames omitted
Caused by: org.hsqldb.HsqlException: incompatible data type in conversion
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.error.Error.error(Unknown Source)
    ... 60 common frames omitted

【问题讨论】:

    标签: java jdbc mybatis hsqldb


    【解决方案1】:

    事实证明,默认的ZonedDateTimeTypeHandler 假定 jdbc 驱动程序知道如何处理 ZonedDateTime,而 hsqldb 或 oracle 则不是这样

    public class ZonedDateTimeTypeHandler extends BaseTypeHandler<ZonedDateTime> {
      @Override
      public void setNonNullParameter(PreparedStatement ps, int i, ZonedDateTime parameter, JdbcType jdbcType) throws SQLException {
        ps.setObject(i, parameter);
      }
    
      @Override
      public ZonedDateTime getNullableResult(ResultSet rs, String columnName) 
     throws SQLException {
        return rs.getObject(columnName, ZonedDateTime.class);
      }
      ...
    }
    

    我使用自定义处理程序解决了这个问题,该处理程序在后台使用 setTimestamp(...)getTimestamp(...)

    @AllArgsConstructor
    public class ZonedDateTimeTypeHandler extends BaseTypeHandler<ZonedDateTime> {
        private final ZoneId zoneId;
    
        @Override
        public void setNonNullParameter(PreparedStatement ps, int i, ZonedDateTime parameter, JdbcType jdbcType) throws SQLException {
            ps.setTimestamp(i, Timestamp.from(parameter.toInstant()));
        }
    
        @Override
        public ZonedDateTime getNullableResult(ResultSet rs, String columnName) throws SQLException {
            Timestamp ts = rs.getTimestamp(columnName);
            return ts == null ? null : ts.toInstant().atZone(zoneId);
        }
    
        @Override
        public ZonedDateTime getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
            Timestamp ts = rs.getTimestamp(columnIndex);
            return ts == null ? null : ts.toInstant().atZone(zoneId);
        }
    
        @Override
        public ZonedDateTime getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
            Timestamp ts = cs.getTimestamp(columnIndex);
            return ts == null ? null : ts.toInstant().atZone(zoneId);
        }
    }
    

    我使用以下代码注册的

        @Bean
        public SqlSessionFactory sqlSessionFactory(DataSource dataSource) {
            ZoneId zoneId = ZoneId.of("UTC");
            TransactionFactory transactionFactory = new JdbcTransactionFactory();
            Environment environment = new Environment("default", transactionFactory, dataSource);
            org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration(environment);
            configuration.getTypeHandlerRegistry().register(ZonedDateTime.class, new ZonedDateTimeTypeHandler(zoneId));
            configuration.addMapper(MyMapper.class);
            return new SqlSessionFactoryBuilder().build(configuration);
        }
    

    【讨论】:

      猜你喜欢
      • 2017-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-11
      • 2011-09-26
      • 2021-06-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多