4

I need help with Spring Boot and MyBatis integration. I have an issue with custom BaseTypeHandler. I've created a mapper:

@MappedTypes({LocalDateTime.class})
public class LocalDateTimeHandler extends BaseTypeHandler<LocalDateTime> {

I've added a type handler:

sqlSessionFactory.setTypeHandlers(new LocalDateTimeHandler[]{new LocalDateTimeHandler()});

And I have next error:

org.apache.ibatis.executor.ExecutorException: No constructor found in com.some.space.SomeObject matching [java.lang.Integer, java.sql.Timestamp, java.sql.Timestamp]

Where SomeObject looks like:

public class SomeObject {
    private Long id;
    private LocalDateTime created;
    private LocalDateTime updated;

    public SomeObject(Integer id, LocalDateTime created, LocalDateTime updated){
    //..........
    }
}

I using mybatis-spring and spring-boot-starter-web version 1.3.2.

All examples about working with TypeHandlers are on the XML configuration, but I need to use Java configs way. What I'm doing wrong?


UPD:

My mapper:

@Component
@Mapper
public interface SomeObjectRepository {

    @Select("SELECT * FROM some_objects")
    @Results(value = {
            @Result(property = "created", column = "created_date", typeHandler = LocalDateTimeTypeHandler.class, jdbcType = JdbcType.TIMESTAMP),
            @Result(property = "updated", column = "updated_date", typeHandler = LocalDateTimeTypeHandler.class, jdbcType = JdbcType.TIMESTAMP)
    })
    List<SomeObject> getAll();
}
Alex Lybetsky
  • 41
  • 1
  • 1
  • 4

1 Answers1

0

You haven't instructed mybatis to use your type handler for timestamp fields. So it converts timestamp fields from the database using default type handler for that JDBC type.

If you want to do this only in some queries do like this for xml mapping:

<result property="created" column="created"
    typeHandler="com.mycompany.myapp.LocalDateTimeHandler"/>

Or via annotations:

@Result(property = "created", column = "created",
        typeHandler=LocalDateTimeHandler.class)

If you want to make it global and use it for all fields of the specific JDBC type add @MappedJdbcTypes to you TypeHandler:

@MappedJdbcTypes({JdbcType.TIMESTAMP})
@MappedTypes({LocalDateTime.class})
public class LocalDateTimeHandler extends BaseTypeHandler<LocalDateTime> {

Depending on the version of mybatis you are using you may need to set includeNullJdbcType=true on the @MappedJdbcTypes annotation.

See documentation for details about this.

  • Thank you for your response. But it doesn't work in my case. The MyBatis trying to use constructor with (Integer, Timestamp, Timestamp). – Alex Lybetsky Nov 08 '18 at 13:19
  • @AlexLybetsky Get rid of the constructor and just use public instance variables. MyBatis will find them. You don't need setters. If you are displaying the object in JSP with `${bean.value}`, you will need getters. – Chloe Feb 28 '19 at 22:30
  • @Roman Konoval I want to write typeHandler for Timestamp. And it should be visible globally. I did exact above stepts. 1. Wrote own typeHandler. 2. added MappedJdbcTypes and MappedTypes annotations 3. made entry in config.xml But still typehandler is not visible for Timestamp datatype – Rujuta S Mar 16 '21 at 13:34