TypeHandler with @MappedJdbcTypes

717 views
Skip to first unread message

Bertrand Guay-Paquet

unread,
Feb 25, 2016, 2:54:57 PM2/25/16
to mybatis-user
Hello,

I want to configure a type handler to convert Date columns to LocalDate
(Java 8), but I am having trouble registering it. I based my typeHandler
on the MyBatis doc and this project
https://github.com/javaplugs/mybatis-java-time.

Mapper:
<resultMap id="clientResult" type="client">
<id property="id" column="id" />
<result property="name" column="name" />
<result property="birthday" column="birthday" />
</resultMap>

Client class:
public class Client {
private Long id;
private String name;
private java.time.LocalDate birthday;
}

The type handler:
@MappedJdbcTypes(value = JdbcType.DATE)
public class LocalDateHandler extends BaseTypeHandler<java.time.LocalDate> {
...
}

I get this error on startup:
org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML.
Cause: java.lang.IllegalStateException: No typehandler found for
property birthday

After some debugging and experimenting, I found multiple solutions.

Solution #1
Remove @MappedJdbcTypes

Solution #2
Change the @MappedJdbcTypes annotation to use the undocumented
includeNullJdbcType = true
@MappedJdbcTypes(value = JdbcType.DATE, includeNullJdbcType = true)

Solution #3
Add a jdbcType to the resultMap property:
<result property="birthday" column="birthday" jdbcType="DATE" />

However, I would have expected everything to work as presented above.
What's going on? What should I do?

Regards,
Bertrand

Iwao AVE!

unread,
Feb 25, 2016, 9:40:33 PM2/25/16
to mybatis-user
Hi Bertrand,

Could you test it against 3.4.0-SNAPSHOT?
I've made some changes recently and it should work if the driver
reports the JDBC type as expected.

I would still recommend solution #1 (not to specify jdbcType) unless
you want to use different type handlers on a single java type
depending on the JDBC type.

Regards,
Iwao
> --
> You received this message because you are subscribed to the Google Groups
> "mybatis-user" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to mybatis-user...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Bertrand Guay-Paquet

unread,
Feb 26, 2016, 11:14:49 AM2/26/16
to mybati...@googlegroups.com
Hi Iwao,

Thanks for your reply. I've tested it against 3.4.0-SNAPSHOT and got the
same error.

My understanding is that the exception is thrown while the XML
configuration is parsed so before the driver has any chance to be involved.

I'm not sure I understand the recommendation to go with solution #1. I
want to have all DATE columns handled by my custom TypeHandler instead
of the default one. Essentially, I want to do what ExampleTypeHandler
(from the docs) does for VARCHAR, but for DATE columns instead. This
way, if I use a Map result type, it will contain LocalDate objects
instead of Date. If I don't use @MappedJdbcTypes, it seems that this
won't happen.

The stack trace:
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 birthday
at
org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:117)
at
org.apache.ibatis.builder.xml.XMLConfigBuilder.parse(XMLConfigBuilder.java:95)
Caused by: org.apache.ibatis.builder.BuilderException: Error parsing
Mapper XML. Cause: java.lang.IllegalStateException: No typehandler found
for property birthday
at
org.apache.ibatis.builder.xml.XMLMapperBuilder.configurationElement(XMLMapperBuilder.java:120)
at
org.apache.ibatis.builder.xml.XMLMapperBuilder.parse(XMLMapperBuilder.java:92)
at
org.apache.ibatis.builder.annotation.MapperAnnotationBuilder.loadXmlResource(MapperAnnotationBuilder.java:169)
at
org.apache.ibatis.builder.annotation.MapperAnnotationBuilder.parse(MapperAnnotationBuilder.java:120)
at
org.apache.ibatis.binding.MapperRegistry.addMapper(MapperRegistry.java:72)
at
org.apache.ibatis.binding.MapperRegistry.addMappers(MapperRegistry.java:97)
at
org.apache.ibatis.binding.MapperRegistry.addMappers(MapperRegistry.java:105)
at
org.apache.ibatis.session.Configuration.addMappers(Configuration.java:702)
at
org.apache.ibatis.builder.xml.XMLConfigBuilder.mapperElement(XMLConfigBuilder.java:351)
at
org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:115)
... 17 more
Caused by: java.lang.IllegalStateException: No typehandler found for
property birthday
at
org.apache.ibatis.mapping.ResultMapping$Builder.validate(ResultMapping.java:151)
at
org.apache.ibatis.mapping.ResultMapping$Builder.build(ResultMapping.java:140)
at
org.apache.ibatis.builder.MapperBuilderAssistant.buildResultMapping(MapperBuilderAssistant.java:382)
at
org.apache.ibatis.builder.xml.XMLMapperBuilder.buildResultMappingFromContext(XMLMapperBuilder.java:378)
at
org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElement(XMLMapperBuilder.java:280)
at
org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElement(XMLMapperBuilder.java:252)
at
org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElements(XMLMapperBuilder.java:244)
at
org.apache.ibatis.builder.xml.XMLMapperBuilder.configurationElement(XMLMapperBuilder.java:116)
... 26 more

Regards,
Bertrand

Iwao AVE!

unread,
Feb 27, 2016, 1:17:19 PM2/27/16
to mybatis-user
Ah, you're right. The fix I've made was mostly for auto-mapping.

Could you create a new issue on the tracker?
https://github.com/mybatis/mybatis-3/issues
I'll see if it's possible to improve the behavior without breaking
backward compatibility.

Thank you,
Iwao

Bertrand Guay-Paquet

unread,
Feb 29, 2016, 7:30:25 PM2/29/16
to mybati...@googlegroups.com

Iwao AVE!

unread,
Feb 29, 2016, 8:03:05 PM2/29/16
to mybatis-user
Thanks!
Reply all
Reply to author
Forward
0 new messages