Dont know how to use a resultMap with collectoins - always says cant find my result map which is right there!

2,038 views
Skip to first unread message

Simon

unread,
Jul 25, 2010, 8:22:03 AM7/25/10
to mybatis-user
Page 31 of the user guide has an impressive display of resultMap
functionality which puts collections etc. inside without having to get
each level.

E.g. if you have a users table, and a roles table which has user id, I
assume you can retrieve a user with all his roles in one hit.

The UserMapper.xml might be something like this:

<resultMap id="userRolesResultMap" type="com.skillkash.ge.beans.User">
<result property="id" column="user_id"/>
<collection property="roles" ofType="com.skillkash.ge.beans.Role">
<result property="id" column="role_id"/>
</collection>
</resultMap>

<select id="select" resultType="userRolesResultMap">
select u.id as user_id
,name
,r.id as stake_id
,r.description
from users u, roles r
where u.id = #{value}
</select>

and then 2 beans like this:

package bla
public class User {
private long id;
private String name;
private List<Role> roles;
// getters and setters for id, name and roles
}

package bla
public class Role {
private long id;
private String description;
// getters and setters for id, description
}

So, without any exmaple to go by, Im guessing that the rusult map can
magically put the roles into the users.

But all I get is this error:

Error resolving class . Cause: org.apache.ibatis.type.TypeException:
Could not resolve type alias 'userRolesResultMap'.

I dont get it, the definition of the userRolesResultMap is right there
above the select Sql, and it delares the type to be User, so how can
it not find it?

If anyone has a single example, with the java beans, DB table
structure and mapper xml I would be very very greatful.

Simon

unread,
Jul 25, 2010, 1:16:43 PM7/25/10
to mybatis-user
Got a step furhter by trial and error hacking.

Found that it kind of works if you avoid using any reference to a
"ResultMap", as there is no documentation how to complete one of
these.

Instead the following half works:

<resultMap id="com.skillkash.ge.beans.User"
type="com.skillkash.ge.beans.User">
<result property="id" column="user_id"/>
<collection property="roles" ofType="com.skillkash.ge.beans.Role">
<result property="id" column="role_id"/>
</collection>
</resultMap>

<select id="select" resultType="com.skillkash.ge.beans.User">
select u.id as user_id
,name
,r.id as role_id
,r.description
from users u, roles r
where u.id = #{value}
</select>

However, now we get stuck with:

org.apache.ibatis.exceptions.TooManyResultsException: Expected one
result (or null) to be returned by selectOne(), but found: 2
at
org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:
42)
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:
66)

This is because I ahve two roles for the chosen user, i.e. the sql
returns something like this:
userid name role_id description
1 Simon 1 Role A
1 Simon 2 Role B

In otherwods, Mybatis is treating this as two users, not one user with
two roles. So how does the sql and mapping on page 31 of the user
guide work, which must produce the same many rows for one Blog?

Simon.

Simon

unread,
Jul 25, 2010, 2:05:42 PM7/25/10
to mybatis-user
Result! I found one example of someone else who has used a resultMap
for this kind of thing:

http://groups.google.com/group/mybatis-user/browse_thread/thread/f7212c11215d278d

and was immedatly able to spot the error: I used "resultType" instead
of "resultMap".

However, now I find out the gotcha - it only maps the columns you
explicitly declare in the result map, and ignores all the columns from
the sql result and in the beans which have identical names. So its
much less work to not use collections in result maps, but instead to
do this by hand, i.e. select a user letting mybatis do all the result
mapping of all the columns for you, selectAll for the roles for the
given userID, then manually assign the list of roles to the user using
its setRoles(List<role> roles) method, as we have about 10 more
columns than those 2 shown here. Does anyone know a way round this
apparent downside? If each table has 20 or so columns, and they
change resonably frequently, writing and maintaing these "manual"
result maps would be too expensive for the benifit (saving 2 calls)?

Is there anywhere we can document examples (e.g. a public documention
wiki) of myBatis excellent but difficult to figure out features, for
all the beginners like me to save time? If not, ill start a mybatis
examples wiki on my site.
Reply all
Reply to author
Forward
0 new messages