Title: Problem with HashMap and List

Hi,

I've just encountered a big problem with my iBatis-Application. First I implemented a DOM and used it in the "class="-Properties of my resultMaps. Now we decided, to change the architecture to a HashMap-Structure of the following: HashMap as some Lists as values: the Lists have HashMaps again. Here is an example of my xml-File to illustrate, what I want to do:

<resultMap id="a" class="java.util.HashMap">
        <result property="aa" select="loadAA"/>
        <result property="id" column="id"/>
</resultMap>   
<select id="loadA" resultMap="a">
        Select id from tableA where id = 1
</select>

<resultMap id="aa" class="java.util.HashMap">
        <result property="id" column="id"/>
</resultMap>   
<select id="loadAA" resultMap="aa">
        Select id from tableA
</select>

The first select returns one result --> a HashMap, the second select returns numerous results --> n HashMaps that should be mapped as a List of HashMaps.

When we implement it as a DOM and exchange the classes in the resultMaps with the ones below, the same code works fine:

class A {
        private Collection aa;
        private int id;
        //getters and setters
}

class AA {
        private int id;
}

When we try to run the application we get:

Exception in thread "main" org.springframework.jdbc.UncategorizedSQLException: SqlMapClient operation; uncategorized SQLException for SQL []; SQL state [null]; error code [0];  

--- The error occurred in test.xml. 
--- The error occurred while applying a result map. 
--- Check the a
--- Check the result mapping for the 'aa' property. 
--- Cause: java.sql.SQLException: Error: executeQueryForObject returned too many results.; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException:

After reviewing the sources we've come up with an explanation:

The Method BasicResultMap.getResults(RequestScope request, ResultSet rs) the targetType for further calls is set:

if (resultClass == null) {
          throw new SqlMapException("The result class was null when trying to get results for ResultMap named " + getId() + ".");

} else if (Map.class.isAssignableFrom(resultClass)) {
          columnValues[i] = getNestedSelectMappingValue(request, rs, mapping, Object.class);
} else if (DomTypeMarker.class.isAssignableFrom(resultClass)) {
          Class javaType = mapping.getJavaType();
          if (javaType == null) {
            javaType = DomTypeMarker.class;
          }
          columnValues[i] = getNestedSelectMappingValue(request, rs, mapping, javaType);
} else {
          Probe p = ProbeFactory.getProbe(resultClass);
          Class type = p.getPropertyTypeForSetter(resultClass, mapping.getPropertyName());
          columnValues[i] = getNestedSelectMappingValue(request, rs, mapping, type);
}

So, how can we get around this? If the else-Statements would be something like:

if (resultClass == null) {
          throw new SqlMapException("The result class was null when trying to get results for ResultMap named " + getId() + ".");

} else if (DomTypeMarker.class.isAssignableFrom(resultClass)) {
          Class javaType = mapping.getJavaType();
          if (javaType == null) {
            javaType = DomTypeMarker.class;
          }
          columnValues[i] = getNestedSelectMappingValue(request, rs, mapping, javaType);
} else if (Map.class.isAssignableFrom(resultClass)) {
          columnValues[i] = getNestedSelectMappingValue(request, rs, mapping, Object.class);
} else {
          Probe p = ProbeFactory.getProbe(resultClass);
          Class type = p.getPropertyTypeForSetter(resultClass, mapping.getPropertyName());
          columnValues[i] = getNestedSelectMappingValue(request, rs, mapping, type);
}

Our problem would be solvalbe implementing a DummyDO-Class:
 
class DummyDO extends HashMap implements DomTypeMarker


BUT, due to the order of the else-Statements this doesn't work and again, targetType is set to java.lang.Object and later, the "getQueryForObject"-Method is called.

How can we get around this?

Stefan Friedrich

Reply via email to