upgraded to mybatis-spring 1.3.0 /mybatis 3.4 issue with typeHandler recoginition?

152 views
Skip to first unread message

Rick R

unread,
Aug 16, 2016, 11:23:20 AM8/16/16
to mybati...@googlegroups.com

Previously I was using mybatis 3.2.8 and mybatis-spring 1.2.2
and I was setting up the typehandler recognition as such:

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="ncsAppDS"/>
<property name="typeAliasesPackage" value="com.ncs.data.domain"/>
<property name="typeHandlersPackage" value="com.ncs.data.services.typehandler"/>
</bean>

My YNBooleanHandler :

     @MappedJdbcTypes(JdbcType.CHAR)
      public class YNBooleanTypeHandler extends BaseTypeHandler<Boolean> {  //.... code }

And my result map property worked just fine as:

     <result column="shared_flg" property="specification.shared"  /> <!-- property is java type boolean -->

And it worked just mapping to the Java boolean property.

Upon upgrading to 3.4.1 and mybatis-spring 1.3.0 the above no longer works unless I declare the type handler explicitly in the result?

I needed:

     <result column="shared_flg" property="specification.shared"  typeHandler="com.ncs.data.services.typehandler.YNBooleanCharTypeHandler"/>
 
It would be nice to not have to go back and add all the typeHandlers to my result map properties, but I'll do it if need be... wondering what changed config was that I might have missed?

I do notice that mybatis-spring docs do not even mentioning registering the type handlers package? http://www.mybatis.org/spring/factorybean.html  (Not sure if there once was documentation on it?) 

--
Rick R

Iwao AVE!

unread,
Aug 16, 2016, 12:29:36 PM8/16/16
to mybatis-user
Hi Rick,

If the property type is primitive boolean, you may need to add another annotation to your YNBooleanTypeHandler.
@MappedTypes(boolean.class)

Regards,
Iwao

Rick R

unread,
Aug 16, 2016, 12:49:25 PM8/16/16
to mybati...@googlegroups.com
On Tue, Aug 16, 2016 at 12:28 PM, Iwao AVE! <hara...@gmail.com> wrote:
Hi Rick,

If the property type is primitive boolean, you may need to add another annotation to your YNBooleanTypeHandler.
@MappedTypes(boolean.class)

You're awesome Iwao! :)
That was it. Thanks so much!  (Interesting that it wasn't needed in the earlier versions)

 

--
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+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Rick R

Iwao AVE!

unread,
Aug 16, 2016, 1:02:47 PM8/16/16
to mybatis-user
You're very welcome =)

FYI, the behavior changed in 3.3.0 by the following fix.
https://github.com/mybatis/mybatis-3/issues/165

Rick R

unread,
Aug 23, 2016, 10:00:51 AM8/23/16
to mybati...@googlegroups.com
Ok, I'm going to come back to this a bit since I'm curious about something.
In our case I need to type handlers for boolean.. some columns are 0/1 some are Y/N

On retrievals things work only if I also declare the jdbcType at the result map element level (eg jdbcType="CHAR" )
Even though on the typeHandlers I've set the various jdbc types declared:

@MappedTypes(boolean.class)
@MappedJdbcTypes(value={JdbcType.VARCHAR, JdbcType.CHAR}, includeNullJdbcType=true)

@MappedTypes(boolean.class)
@MappedJdbcTypes(value={JdbcType.INTEGER, JdbcType.TINYINT, JdbcType.NUMERIC}, includeNullJdbcType=true)

It looks like according to the docs, I shouldn't need to set the jdbcType on the result map element if I also set the MappedJdbcTypes, so I'm a bit confused what the issue is?  It must have to do with the fact that I'm mapping both typeHandlers to a boolean? 
I can go  through and set the jdbcTypes on the elements in the result maps, but it would sort of be nice to not have to do this.


On Tue, Aug 16, 2016 at 12:28 PM, Iwao AVE! <hara...@gmail.com> wrote:

--
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+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Rick R

Iwao AVE!

unread,
Aug 25, 2016, 7:36:55 AM8/25/16
to mybatis-user
Hi Rick,

You cannot assign two type handlers to the same combination of java type and jdbc type (including null jdbc type).
This makes sense because MyBatis uses this combination to pick a type handler.

With the current implementation, you would have to specify jdbcType on every boolean property if you want to use two type handlers for a single java type.
I'll see if it's possible to overcome the inconvenience.

Regards,
Iwao

Rick R

unread,
Aug 25, 2016, 9:04:51 AM8/25/16
to mybati...@googlegroups.com
On Thu, Aug 25, 2016 at 7:36 AM, Iwao AVE! <hara...@gmail.com> wrote:
Hi Rick,

You cannot assign two type handlers to the same combination of java type and jdbc type (including null jdbc type).
This makes sense because MyBatis uses this combination to pick a type handler.

Makes sense. No worries. I went and declared all the jdbc types. I also am considering just a single handler that can toggle between handling boolean vs y/n char from a single handler.  I just to investigate more in figuring out how to get the jdbcType within the handler methods get methods.



With the current implementation, you would have to specify jdbcType on every boolean property if you want to use two type handlers for a single java type.
I'll see if it's possible to overcome the inconvenience.

Regards,
Iwao


2016-08-23 23:00 GMT+09:00 Rick R <ric...@gmail.com>:
Ok, I'm going to come back to this a bit since I'm curious about something.
In our case I need to type handlers for boolean.. some columns are 0/1 some are Y/N

On retrievals things work only if I also declare the jdbcType at the result map element level (eg jdbcType="CHAR" )
Even though on the typeHandlers I've set the various jdbc types declared:

@MappedTypes(boolean.class)
@MappedJdbcTypes(value={JdbcType.VARCHAR, JdbcType.CHAR}, includeNullJdbcType=true)

@MappedTypes(boolean.class)
@MappedJdbcTypes(value={JdbcType.INTEGER, JdbcType.TINYINT, JdbcType.NUMERIC}, includeNullJdbcType=true)

It looks like according to the docs, I shouldn't need to set the jdbcType on the result map element if I also set the MappedJdbcTypes, so I'm a bit confused what the issue is?  It must have to do with the fact that I'm mapping both typeHandlers to a boolean? 
I can go  through and set the jdbcTypes on the elements in the result maps, but it would sort of be nice to not have to do this.

--
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+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Rick R

Rick R

unread,
Sep 30, 2016, 9:57:46 AM9/30/16
to mybati...@googlegroups.com
Bring this up again since now I found another issue when upgrading relating to boolean type handlers.
I have two type handlers for boolean since unfortunately our legacy db has Y/N for some an 0/1 for others.

In previous versions I was able to just do the following, without declaring the handler.

UPDATE EXECUTION_T SET DELETE_FLG = #{markDeleted,jdbcType=CHAR}  WHERE EXECUTION_ID = #{executionId}


The above no longer works, however, and I now need to explicitly tell it the handler


UPDATE EXECUTION_T SET DELETE_FLG = #{markDeleted,jdbcType=CHAR,typeHandler=com.ncs.data.services.typehandler.YNBooleanTypeHandler}
WHERE EXECUTION_ID = #{executionId}

This is going to be quite annoying to have to go through and change them all. Keep in mind in "previous" versions this was not an issue, so it's why I'm bringing it up. Not sure if you could revert to the previous behavior?

My handlers are set up as...

@MappedTypes(boolean.class)
@MappedJdbcTypes(value={JdbcType.VARCHAR, JdbcType.CHAR}, includeNullJdbcType=true)
public class YNBooleanTypeHandler extends BaseTypeHandler<Boolean> {
and
@MappedTypes(boolean.class)
@MappedJdbcTypes(value={JdbcType.INTEGER, JdbcType.TINYINT, JdbcType.NUMERIC}, includeNullJdbcType=true)
public class ZeroOneBooleanTypeHandler extends BaseTypeHandler<Boolean> {

--
Rick R

Iwao AVE!

unread,
Oct 1, 2016, 1:15:38 PM10/1/16
to mybatis-user

Rick R

unread,
Oct 1, 2016, 3:50:43 PM10/1/16
to mybati...@googlegroups.com
Ok wow, your example helped illustrate something (related to something you mentioned earlier in this thread from awhile back.)

Turns out in this case on an update I needed BOTH mapped types of Boolean AND boolean... even though I'm using in this case ONLY a primitive boolean????
Seems so odd (since for other updates it's not an issue.) When I changed the mapping of YN handler (like you have) from just boolean.class to

@MappedTypes({ Boolean.class, boolean.class })

then it worked!

I would think for just a primitive boolean I'd only need:

@MappedTypes(boolean.class)

BUT  here is the crazy thing.... in other classes the update works just fine for a primitive boolean for a char jdbcType and ONLY using the single mappedType of boolean.

I don't suppose it will hurt to use both mappedTypes but man it really has me stumped as to why this one update causes an issue, if I do not also include Boolean.class as a MappedType, I see it try to use an integer 0/1 for the update when I only map boolean to the YNHandler:

15:46:35.604 [main] DEBUG c.n.d.s.m.s.E.updateDeleteFlag - ==>  Preparing: UPDATE EXECUTION_T SET DELETE_FLG = ?, UPDATED_TS = CURRENT_TIMESTAMP WHERE EXECUTION_ID = ? 
15:46:35.604 [main] DEBUG c.n.d.s.m.s.E.updateDeleteFlag - ==> Parameters: 1(Integer), 104545(Long)

For the mapper statement

<update id="updateDeleteFlag">
UPDATE EXECUTION_T SET DELETE_FLG = #{markDeleted,jdbcType=CHAR}, UPDATED_TS = CURRENT_TIMESTAMP WHERE EXECUTION_ID = #{executionId}
</update>






Iwao AVE!

unread,
Oct 5, 2016, 1:14:01 PM10/5/16
to mybatis-user
Glad to know that you found a solution!
If the statement takes multiple parameters, they are put into a map, so boolean will be converted to java.lang.Boolean implicitly.

Regards,
Iwao
Reply all
Reply to author
Forward
0 new messages