MyBatis cannot work with joda DateTime?

11.2k views Asked by At

I'm using MyBatis 3.2, and want to map Oracle DATE data type to Java org.joda.time.DateTime data type.

Here is my configuration:

<resultMap id="something" type="com.myself.SomeClass">
  <result property="creationDate" column="CREATION_DATE" javaType="org.joda.time.DateTime" />
</resultMap>

But I get following error:

Caused by: org.apache.ibatis.builder.BuilderException
         : Error parsing SQL Mapper Configuration. 
Cause    : org.apache.ibatis.builder.BuilderException
         : Error parsing Mapper XML. 
Cause    : java.lang.IllegalStateException
         : No typehandler found for property creationDate

Is my configuration correct? Or is it caused by my Oracle data type is DATE instead of DATETIME? Does MyBatis support joda DateTime?

3

There are 3 answers

0
Francis Zabala On BEST ANSWER

I think you need to use TypeResolver to handle JodaTime to Oracle DateTime. I had experience with this with MyBatis with MySQL and you might use this is a guide that might help you with your issue.

I used this github project as guide on how to use TypeResolver: https://github.com/LukeL99/joda-time-mybatis

And in one of my mappers, I have this code:

<result column="expiryDate" property="expiryDate" javaType="org.joda.time.DateTime" typeHandler="org.joda.time.mybatis.handlers.DateTimeTypeHandler"/>

The org.joda.time.mybatis.handlers.DateTimeTypeHandler is class from the github project I posted.

I hope this would help guide you.

1
Peter Pan On

I think MyBatis don't support Joda DateTime. It maybe caused by mybatis couldn't serialize Joda DateTime object into correct format for JDBC sql. So, you must use Java type "Date".

0
Mike On

There is org.mybatis:mybatis-typehandlers-jsr310 for java 8 DateTime support.
I've copied needed classes to my project and ported them to JodaTime.
After that you can use type handlers in select statements and result definitions as usual.

@Select("select p.transaction_id from dly_mstr_curr_trd_prg p "
        + "where p.start_time < #{threshold, typeHandler=org.apache.ibatis.type.LocalDateTimeTypeHandler} "
        + "and failure_reason is null")
Collection<BigDecimal> selectStaleNotFailedTransactions(@Param("threshold") LocalDateTime threshold);

or

@Result(property = "transaction.transactionPostingDate", column = "TXN_PSTG_D", typeHandler=LocalDateTimeTypeHandler.class),

Here is example of ported class:

/**
 * @author Tomas Rohovsky
 */
public class LocalDateTypeHandler extends BaseTypeHandler<LocalDate> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, LocalDate parameter, JdbcType jdbcType)
            throws SQLException {
        ps.setDate(i, Date.valueOf(parameter.toString("yyyy-MM-dd HH:mm:ss")));
    }

    @Override
    public LocalDate getNullableResult(ResultSet rs, String columnName) throws SQLException {
        Date date = rs.getDate(columnName);
        return getLocalDate(date);
    }

    @Override
    public LocalDate getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        Date date = rs.getDate(columnIndex);
        return getLocalDate(date);
    }

    @Override
    public LocalDate getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        Date date = cs.getDate(columnIndex);
        return getLocalDate(date);
    }

    private static LocalDate getLocalDate(Date date) {
        return date == null ? null : LocalDate.parse(date.toLocalDate().toString());
    }
}