jdbcType is not recognized in XML mapping?

331 views
Skip to first unread message

jdevelop

unread,
Apr 14, 2014, 11:40:50 PM4/14/14
to mybati...@googlegroups.com
Hello!

Given the SQL mapping sample:

WHERE cl.user_id = #{value, javaType=java.util.UUID, jdbcType=BINARY, typeHandler=dao.UUIDTypeHandler}

it complains that "There is no getter for property named 'value' in 'class java.util.UUID'"

Caused by: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'value' in 'class java.util.UUID'
    at org.apache.ibatis.reflection.Reflector.getGetInvoker(Reflector.java:377)
    at org.apache.ibatis.reflection.MetaClass.getGetInvoker(MetaClass.java:167)
    at org.apache.ibatis.reflection.wrapper.BeanWrapper.getBeanProperty(BeanWrapper.java:149)
    at org.apache.ibatis.reflection.wrapper.BeanWrapper.get(BeanWrapper.java:45)
    at org.apache.ibatis.reflection.MetaObject.getValue(MetaObject.java:113)
    at org.apache.ibatis.scripting.defaults.DefaultParameterHandler.setParameters(DefaultParameterHandler.java:72)
    at org.apache.ibatis.executor.statement.PreparedStatementHandler.parameterize(PreparedStatementHandler.java:77)
    at org.apache.ibatis.executor.statement.RoutingStatementHandler.parameterize(RoutingStatementHandler.java:58)
    at org.apache.ibatis.executor.ReuseExecutor.prepareStatement(ReuseExecutor.java:76)
    at org.apache.ibatis.executor.ReuseExecutor.doQuery(ReuseExecutor.java:53)
    at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:259)
    at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:132)
    at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:115)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.select(DefaultSqlSession.java:124)


So tracing back to mybatis-3.2.2-sources.jar!/org/apache/ibatis/scripting/defaults/DefaultParameterHandler.java:69 and there is the call to typeHandlerRegistry.hasTypeHandler(parameterObject.getClass()), which, in turn, goes to mybatis-3.2.2-sources.jar!/org/apache/ibatis/type/TypeHandlerRegistry.java:140 and then, since jdbcType argument is null (see the code below)

  public boolean hasTypeHandler(Class<?> javaType) {
    return hasTypeHandler(javaType, null);
  }

and then mybatis-3.2.2-sources.jar!/org/apache/ibatis/type/TypeHandlerRegistry.java:180 fails to find a type handler.

So the question is - what's wrong there? And how to pass jdbctype explicitly to parameters?

Eduardo Macarron

unread,
Apr 15, 2014, 2:46:06 AM4/15/14
to mybati...@googlegroups.com
Just a hint but 1st try removing the spaces after the comma, or upgrade to 3.2.7


--
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.

Eugene Dzhurinsky

unread,
Apr 15, 2014, 9:42:43 AM4/15/14
to mybati...@googlegroups.com
On Tue, Apr 15, 2014 at 08:46:06AM +0200, Eduardo Macarron wrote:
> Just a hint but 1st try removing the spaces after the comma, or upgrade to
> 3.2.7

I tried both of the ways you've suggested, and neither worked. So I ended up
in creation of a dumb wrapper class with the single public property - and that
solved the problem. But it's just ... weird. The problem persists for years,
because I've found the same workaround I used in the Java code dated back at
2006.

--
Eugene N Dzhurinsky

Guy Rouillier

unread,
Apr 15, 2014, 12:25:44 PM4/15/14
to mybati...@googlegroups.com
Not weird at all. You declared the type to be java.util.UUID, which is
a class as opposed to a primitive type like int. So, it's trying to
find a field called "value" that you defined here:

#{value, javaType=java.util.UUID, jdbcType=BINARY,
typeHandler=dao.UUIDTypeHandler}

The issue then is not how to pass jdbcType to parameters, but why didn't
it recognize your type handler? Is dao the fully qualified package name
of your UUIDTypeHandler? Did you identify this type handler in the
<typeHandlers> section of your config.xml file?

--
Guy Rouillier

---
This email is free from viruses and malware because avast! Antivirus protection is active.
http://www.avast.com

Matteo Moci

unread,
Apr 15, 2014, 12:30:37 PM4/15/14
to mybatis-user
Hi, 
I found a similar error some time ago [1], 
maybe it can still help. 
Btw, as Guy suggested, double check type handler's configuration. 

Best, 
Matteo



--
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.



--
Matteo Moci
http://mox.fm

Eugene Dzhurinsky

unread,
Apr 15, 2014, 12:57:42 PM4/15/14
to mybati...@googlegroups.com
On Tue, Apr 15, 2014 at 12:25:44PM -0400, Guy Rouillier wrote:
> The issue then is not how to pass jdbcType to parameters, but why didn't it
> recognize your type handler?

No idea.

> Is dao the fully qualified package name of your UUIDTypeHandler?

Yes

> Did you identify this type handler in the <typeHandlers> section of your config.xml file?

Yes. Moreover, I also provided the type handler explicitly in the parameter mapping.

--
Eugene N Dzhurinsky

Eugene Dzhurinsky

unread,
Apr 15, 2014, 1:00:16 PM4/15/14
to mybati...@googlegroups.com
On Tue, Apr 15, 2014 at 06:30:37PM +0200, Matteo Moci wrote:
> Hi, 
> I found a similar error some time ago [1],  maybe it can still help. 

Annotation does work if mapper interfaces are used, however it's not possible
to use a mapper interface with ResultHandler.

And yes, I double-checked the typehandlers section, all typehandlers are
there, class names are the same, and it works well for result mapping.

So the problem is only related to passing a class type parameter (like UUID)
alone.

--
Eugene N Dzhurinsky

Iwao AVE!

unread,
Apr 15, 2014, 2:19:50 PM4/15/14
to mybatis-user
Hi Eugene,

I guess your mapper method is defined like this.

ResultType selectByUuid(UUID param);

You try to reference the parameter with 'value', but MyBatis looks for
a property named 'value' because UUID is not a simple type.
The easiest workaround is to add @Param annotation.

ResultType selectByUuid(@Param("value")UUID param);

MyBatis then wraps the UUID object in a map under the key 'value', so
the #{value} in the statement should be able to reference the UUID
object as you expect.

Hope this helps,
Iwao

Eugene Dzhurinsky

unread,
Apr 15, 2014, 2:28:17 PM4/15/14
to mybati...@googlegroups.com
On Wed, Apr 16, 2014 at 03:19:50AM +0900, Iwao AVE! wrote:
> Hi Eugene,
>
> I guess your mapper method is defined like this.

I don't have a corresponding method in the mapper interface, since I need to
use an instance of the ResultHandler.

--
Eugene N Dzhurinsky

Guy Rouillier

unread,
Apr 15, 2014, 2:33:48 PM4/15/14
to mybati...@googlegroups.com
We'll need to see some code. Start with the source for your type
handler. I can dummy up some test code for the rest of it. Of course,
even better would be a complete sample project demonstrating the issue.
I see that UUID doesn't have a default constructor; I'm wondering if
that might be causing an issue.

Using classes in TypeHandlers is not a problem in general. I do that
all the time.

Iwao AVE!

unread,
Apr 15, 2014, 2:37:41 PM4/15/14
to mybatis-user
Then you may need to create and pass a map in your code.

Map<String, UUID> map = new ....;
UUID param = ...;
map.put("value", param);
sqlSession.select("statementId", map, resultHandler);

Eugene Dzhurinsky

unread,
Apr 15, 2014, 2:59:23 PM4/15/14
to mybati...@googlegroups.com
On Wed, Apr 16, 2014 at 03:37:41AM +0900, Iwao AVE! wrote:
> Then you may need to create and pass a map in your code.
>
> Map<String, UUID> map = new ....;
> UUID param = ...;
> map.put("value", param);
> sqlSession.select("statementId", map, resultHandler);

That works, but it's ridiculous in the same way as a dedicated wrapper class
with single property. If UUID could be mapped directly into the postgresql
data type - then why just not assume that "value" is object itself?

--
Eugene N Dzhurinsky

Jeff Butler

unread,
Apr 15, 2014, 3:15:22 PM4/15/14
to mybati...@googlegroups.com
This reminds me of an issue we found years ago, but probably never fixed.  There is a workaround embedded in this thread:

https://groups.google.com/forum/#!searchin/mybatis-user/uuid/mybatis-user/DWQogphiU8c/QoKTa5B1S4kJ

It would be interesting to know if the workaround from back then still works.

Jeff Butler

Eduardo Macarron

unread,
Apr 17, 2014, 2:23:41 AM4/17/14
to mybati...@googlegroups.com
Hi guys,

I am afraid this works like this by desing though the results can be sometimes annoying and unexpected. Let me try to explain the rationale.

When MyBatis finds this: "select * from users where id = #{id}"

It should first get the actual value of the parameter and pass it to the type handler.

In this case id can be something different depending on how you called that statement. If you passed an int then the whole input parameter should be passed to the handler, but if you passed a User bean then the id should be got from a getter.

MyBatis decides if the parameter should be passed as a whole to the handler or not by determining if the parameter is "known" or "unknown". Known parameters are those that have a global type handler (may it be by default or custom).

Specifying a typehandler for the binding does not make things different, MyBatis still needs to know if it should pass the whole or a part.

MB3 does not require you to pass the type of the input parameter, and lets you use different parameters for the same statement. Probably the problem you had is a downside of this feature.

The good of this is that it may work or not but the rule is clear (though probably it is not pointed in the docs). 

This can be changed for sure as long as we get to a better but still clear rule. 

Thoughts are welcome!



--
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.
Reply all
Reply to author
Forward
0 new messages