I am investigating the mapping facilities of MyBatis 3.0.5. The database is H2 (1.3.160) in running embedded mode. With the help of the user manual, I got the straightforward parts working. But I am having a hard time mapping a Set that uses a HashMap as the backing storage.
Here's the Java code for the custom collection that has the custom set as field (simplified for brevity)
public class CustomCollection
{
@JsonProperty
private CustomSet<CustomItem> customItems;
public CustomCollection()
{
customItems = new CustomSet<CustomItem>();
}
// other stuff
}
Here's the CustomSet code (again, simplified)
public class CustomSet<E extends CustomItemInterface> extends AbstractSet<E>
{
private ConcurrentHashMap<String, E> items;
public CustomSet()
{
items = new ConcurrentHashMap<String, E>();
}
// other stuff
}
Here's the mapping interface:
public interface CustomCollectionMapper
{
CustomCollection select(@Param("somename") String s1, @Param("someothername") String s2);
}
This is the code that does the call into the Mybatis framework:
SqlSessionFactory sqlSessionFactory = (SqlSessionFactory) servletContext.getAttribute("SqlSessionFactory");
SqlSession session = sqlSessionFactory.openSession();
CustomCollection coll = null;
try
{
CustomCollectionMapper mapper = session.getMapper(CustomCollectionMapper.class);
coll = mapper.select(param1, param2);
}
finally
{
session.close();
}
Here's what I could come up with the mapping XML so far:
<select id="select" resultMap="CustomCollectionMapping">
-- What goes here???
</select>
<resultMap type="com.example.CustomCollection" id="CustomCollectionMapping">
<association property="customItems" javaType="com.example.customSet">
<collection property="items" javaType="HashMap" ofType="com.example.CustomItem" select="selectCustomItems">
</collection>
</association>
</resultMap>
<select id="selectCustomItems" parameterType="map" resultType="com.example.CustomItem">
-- SQL query to return multiple CustomItem rows
</select>
Through various iterations, I got "too many results" error, some other error or nothing (null is returned from the mapper call) but never the result I need. The SQL code works fine by itself and if I ask for a List with a straightforward select statement, I get the rows and the ArrayList back. The problem I am having is having the nested collection objects populated properly.
I have read the manual many times, searched for examples but I could not come up with the correct mapping XML for this purpose. I would appreciate if anyone can help me or point me to a source that can help.
Thanks in advance for all the help.
This is my working example:
<resultMap id="categoryPreferenceValueMap" type="SyncCategoryPreferenceValueModel">
<id property="preferenceTypeId" column="preference_type_id" />
<result property="title" column="title"/>
<result property="index" column="type_index"/>
<result property="updatedAt" column="category_updated_at" />
<collection property="preferences" column="p_preference_id" ofType="SyncPreferenceModel" >
<id property="preferenceId" column="p_preference_id" />
<result property="title" column="p_preference_title" />
<result property="index" column="preference_index" />
<result property="updatedAt" column="preference_updated_at" />
<collection property="preferenceValues" column="p_v_preference_value_id" ofType="SyncPreferenceValueModel" >
<id property="preferenceValueId" column="p_v_preference_value_id" />
<result property="preferenceValue" column="p_v_preference_value" />
<result property="updatedAt" column="preference_value_updated_at" />
</collection>
</collection>
</resultMap>
This is my query
<select id="getPrefersenceWithValues" resultMap="categoryPreferenceValueMap">
SELECT
PT.preference_type_id, PT.title, PT.type_index,PT.updated_at as category_updated_at,
P.preference_id as p_preference_id , P.title as p_preference_title ,P.index as preference_index,
P.updated_at as preference_updated_at,
PV.preference_value_id as p_v_preference_value_id ,PV.preference_value as p_v_preference_value
FROM preference_types PT
INNER JOIN preferences P ON PT.preference_type_id=P.preference_type_id
INNER JOIN preference_values PV ON P.preference_id=PV.preference_id
ORDER BY type_index
</select>
And output is:
[
{
"preferenceTypeId": "1",
"title": "abc BASICS",
"index": "1",
"updatedAt": 1,
"preferences": [
{
"preferenceId": "1",
"title": "xyz xyz",
"preferenceTypeId": null,
"gender": null,
"index": 1,
"updatedAt": 1,
"preferenceValues": [
{
"preferenceId": null,
"preferenceValueId": "2",
"preferenceValue": "30-60",
"gender": null,
"updatedAt": 0
},
{
"preferenceId": null,
"preferenceValueId": "1",
"preferenceValue": "0-30",
"gender": null,
"updatedAt": 0
}
]
}
]
}
]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With