|
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 |
|
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 <[hidden email]> escribió: > 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 > |
|
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 On Thu, Mar 29, 2012 at 3:14 PM, Eduardo Macarron <[hidden email]> wrote: Looks that you are reading a string value that does not match any of |
|
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 <[hidden email]> escribió: > 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 > > On Thu, Mar 29, 2012 at 3:14 PM, Eduardo Macarron > <[hidden email]> wrote: >> >> 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 >> <[hidden email]> escribió: >> > 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 >> > com.xxx.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 >> > > > |
|
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 On Thu, Mar 29, 2012 at 3:35 PM, Eduardo Macarron <[hidden email]> wrote: I see. Your config looks right. |
|
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! :) |
|
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 On Thu, Mar 29, 2012 at 4:03 PM, Eduardo Macarron <[hidden email]> wrote: Is that because of this line? |
| Powered by Nabble | Edit this page |
