3

I want to use Guava multimap as a resultMap with MyBatis, to return a resultset that has a collection of several one to many entries, but I am not able to figure out the exact syntax for the same. Below is a sample of my table :

+----+---------+----------+-------------+
| ID | PART_ID | NAME     | PART_FAMILY |
+----+---------+----------+-------------+
|  1 |       1 | bush     |         300 |
|  2 |       1 | a-bush   |         300 |
|  3 |       1 | 300-bush |         300 |
|  4 |       2 | nut      |         301 |
+----+---------+----------+-------------+

I want a resultset such that I have a Guava multimap with PART_ID as the key, and NAME and PART_FAMILY as the result.

Ex :

Index 0 :
    Key : 1 //PART_ID
    Value : [NAME: bush, PART_FAMILY: 300]
Index 1 :
    Key : 1
    Value : [NAME: a-bush, PART_FAMILY: 300]
Index 2 :
    Key : 1
    Value : (NAME: 300-bush, PART_FAMILY: 300)  
Index 3 :
    Key : 2
    Value : (NAME: nut, PART_FAMILY: 301)   

And below is my query :

<resultMap id="partsMap" type="com.google.common.collect.Multimap">
    <id column="PART_ID" property="key" />
    //Not sure what to put here
</resultMap>

<select id="getParts" resultMap="partsMap">
    SELECT 
    PART_ID, NAME, PART_FAMILY
    FROM PART_NAMES
    WHERE ${filter}
    ORDER BY PART_ID
</select>

I wanted help with the below points :

  1. Can mybatis return the a resultMap in a Guava MultiMap as per what I have described above?
  2. If yes, can you please help me with the syntax for the same?
  3. If no, then how can I obtain the resultset as mentioned in the example?

Thanks in advance!

Olivier Grégoire
  • 33,839
  • 23
  • 96
  • 137
  • did you try it it can? – Eugene Apr 10 '17 at 11:21
  • 1
    @Eugene , yes, I tried it, and it throws the below exception : Error querying database. Cause: org.apache.ibatis.reflection.ReflectionException: Error instantiating interface com.google.common.collect.Multimap with invalid types () or values (). Cause: java.lang.NoSuchMethodException: com.google.common.collect.Multimap.() – student for life Apr 10 '17 at 11:40
  • 1
    ok so apparently mybatis is trying to initialize `Multimap` via a default constructor, which obviously does not exist. Multimaps are populated only at creation time or via a `Builder`, since they are Immutable. I think that your only option here is to create a `Map` and then use some factory methods to create a `MultiMap` out of that. – Eugene Apr 10 '17 at 11:59
  • `resultMap` requires a constructor. `Multimap` doesn't offer any, nor its various implementations. – Olivier Grégoire Apr 10 '17 at 12:02
  • 2
    @OlivierGrégoire , can I extend the Multimap , provide a constructor, and use this new class instead? – student for life Apr 10 '17 at 12:08
  • 2
    Yes, of course! You should probably use a `ForwardingMultimap` for that use case. That way you only have to define the following: `public class MyMultimap extends ForwardingMultimap { private Multimap delegate = HashMultimap.create(); public MyMultimap() {} @Override public Multimap delegate() { return delegate; } }`. I cant' really help for the mapping, though. – Olivier Grégoire Apr 10 '17 at 12:18

0 Answers0