MyBatis not picking up typehandler in resultmap collection

1,991 views
Skip to first unread message

reuben firmin

unread,
Mar 29, 2012, 2:34:35 PM3/29/12
to mybati...@googlegroups.com
Hello,

I am registering a type handler in code, like so:

        for (Class mapper : mappers) {
            configuration.addMapper(mapper);
        }
        configuration.getTypeHandlerRegistry().register(FieldType.class, new ForgivingEnumTypeHandler<FieldType>(FieldType.class));

        final SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        return builder.build(configuration);

(This type handler returns null if the value in the column cannot be coerced to a value of the enum.)

In my mapper, we have:

    <resultMap id="column" type="com.xxx.Column">
        <result column="id" property="id"/>
        ...
        <collection property="fieldTypes" ofType="com.xxx.FieldType"
                    column="id" select="getFieldTypesForColumn"/>
    </resultMap>

    <!-- mapping table for column <-> field types -->
    <select id="getFieldTypesForColumn" parameterType="int" resultType="com.xxx.FieldType">
...
    </select>

However, when this is run, I get the exception:

[INFO] Caused by: java.lang.IllegalArgumentException: No enum const class us.catalist.iotool.model2.FieldType.some legacy junk
[INFO] at java.lang.Enum.valueOf(Enum.java:196)
[INFO] at org.apache.ibatis.type.EnumTypeHandler.getNullableResult(EnumTypeHandler.java:26)
[INFO] at org.apache.ibatis.type.EnumTypeHandler.getNullableResult(EnumTypeHandler.java:8)
[INFO] at org.apache.ibatis.type.BaseTypeHandler.getResult(BaseTypeHandler.java:29)
[INFO] at org.apache.ibatis.executor.resultset.FastResultSetHandler.getPropertyMappingValue(FastResultSetHandler.java:267)
[INFO] at org.apache.ibatis.executor.resultset.FastResultSetHandler.applyPropertyMappings(FastResultSetHandler.java:250)
[INFO] at org.apache.ibatis.executor.resultset.FastResultSetHandler.getRowValue(FastResultSetHandler.java:224)
[INFO] at org.apache.ibatis.executor.resultset.FastResultSetHandler.handleRowValues(FastResultSetHandler.java:173)
[INFO] at org.apache.ibatis.executor.resultset.FastResultSetHandler.handleResultSet(FastResultSetHandler.java:146)
[INFO] at org.apache.ibatis.executor.resultset.FastResultSetHandler.handleResultSets(FastResultSetHandler.java:112)
[INFO] at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:40)

Why is the statement not picking up the registered handler? 

Thanks

Eduardo Macarron

unread,
Mar 29, 2012, 3:14:52 PM3/29/12
to mybati...@googlegroups.com
Looks that you are reading a string value that does not match any of
the enum values. May it be the problem?

El día 29 de marzo de 2012 20:34, reuben firmin
<reuben...@gmail.com> escribió:

reuben firmin

unread,
Mar 29, 2012, 3:22:23 PM3/29/12
to mybati...@googlegroups.com
Yes, that's why I am trying to use a custom enum typehandler :) 

There is legacy junk in this column which we cannot delete, but which is irrelevant to the future version of the application. My ForgivingEnumTypeHandler, were it called, would return null if it couldn't coerce the enum value.

So why isn't MyBatis sending the enum values to the custom typehandler? 

Thanks

> com.xxx.FieldType.some legacy junk

Eduardo Macarron

unread,
Mar 29, 2012, 3:35:29 PM3/29/12
to mybati...@googlegroups.com
I see. Your config looks right.

We would need to reproduce it. Could you code an small test?

http://code.google.com/p/mybatis/wiki/Test

El día 29 de marzo de 2012 21:22, reuben firmin
<reuben...@gmail.com> escribió:

reuben firmin

unread,
Mar 29, 2012, 3:47:42 PM3/29/12
to mybati...@googlegroups.com
I'm quite confused by the cause, having now figured it out (via my debugger). It was actually reporting a different mapper than the one that was actually causing the error(!) 

The root cause is that applyAutomaticMappings (in FastResultSetHandler) would correctly figure out the typehandler mapping (based on the registry entry), so sometimes the typehandler worked; however, applyPropertyMappings pulls the typehandler mapping off the resultmap, and so therefore misses the typehandler mapping (somehow), which would cause other statements to fail. Why this leads to the wrong mapper being reported I don't know.

If I have time I will code up a test, but please verify the logic of applyPropertyMappings.

Thanks

Eduardo Macarron

unread,
Mar 29, 2012, 4:03:19 PM3/29/12
to mybati...@googlegroups.com
Is that because of this line?
final TypeHandler<?> typeHandler = propertyMapping.getTypeHandler();

That is becuase handlers are calculated while building the result map.

> If I have time I will code up a test, but please verify the logic of
> applyPropertyMappings.

I will take just 15 minutes, I am sure you will in fact save time! :)

reuben firmin

unread,
Mar 30, 2012, 7:37:25 AM3/30/12
to mybati...@googlegroups.com
It took me a lot longer than 15 minutes to figure this out (I originally misreported the cause, so good thing you made me do the test.) The bug is filed at http://code.google.com/p/mybatis/issues/detail?id=570

Thanks
Reply all
Reply to author
Forward
0 new messages