Author: cbegin
Date: Sat May 30 19:54:21 2009
New Revision: 780313

URL: http://svn.apache.org/viewvc?rev=780313&view=rev
Log:
Implemented nested result mappings for joins

Modified:
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/MapperBuilderAssistant.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/xml/XMLMapperBuilder.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/xml/ibatis-3-mapper.dtd
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MetaObject.java
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/builder/MapperConfig.xml
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/builder/NestedBlogMapper.xml
    
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/session/SqlSessionTest.java

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/MapperBuilderAssistant.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/MapperBuilderAssistant.java?rev=780313&r1=780312&r2=780313&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/MapperBuilderAssistant.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/MapperBuilderAssistant.java
 Sat May 30 19:54:21 2009
@@ -310,11 +310,15 @@
 
   private Class resolveResultJavaType(Class resultType, String property, Class 
javaType) {
     if (javaType == null && property != null) {
-      MetaClass metaResultType = MetaClass.forClass(resultType);
-      javaType = metaResultType.getSetterType(property);
+      try {
+        MetaClass metaResultType = MetaClass.forClass(resultType);
+        javaType = metaResultType.getSetterType(property);
+      } catch (Exception e) {
+        //ignore, following null check statement will deal with the situation
+      }
     }
     if (javaType == null) {
-      throw new BulderException("Could not determine javaType for result.  
Specify property or javaType attribute.");
+      throw new BulderException("Could not determine javaType for result 
property " + property + " using javaType " + javaType);
     }
     return javaType;
   }

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/xml/XMLMapperBuilder.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/xml/XMLMapperBuilder.java?rev=780313&r1=780312&r2=780313&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/xml/XMLMapperBuilder.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/xml/XMLMapperBuilder.java
 Sat May 30 19:54:21 2009
@@ -23,7 +23,7 @@
   public XMLMapperBuilder(Reader reader, Configuration configuration, String 
resource) {
     super(configuration);
     this.assistant = new MapperBuilderAssistant(configuration, resource);
-    this.parser = new XPathParser(reader,true,new 
XMLMapperEntityResolver(),configuration.getVariables());
+    this.parser = new XPathParser(reader, true, new XMLMapperEntityResolver(), 
configuration.getVariables());
   }
 
   public void parse() {
@@ -105,42 +105,40 @@
       resultMapElement(resultMapNode);
     }
   }
-  private void resultMapElement(XNode resultMapNode) throws Exception {
-      ErrorContext.instance().activity("processing " + 
resultMapNode.getValueBasedIdentifier());
-      String id = resultMapNode.getStringAttribute("id");
-      String type = resultMapNode.getStringAttribute("type");
-      String extend = resultMapNode.getStringAttribute("extends");
-      if (id == null) {
-        id = resultMapNode.getValueBasedIdentifier();
-      }
-      Class typeClass = resolveClass(type);
-      processChildrenAsResultMap(resultMapNode);
-      Discriminator discriminator = null;
-      List<ResultMapping> resultMappings = new ArrayList<ResultMapping>();
-      List<XNode> resultChildren = resultMapNode.getChildren();
-      for (XNode resultChild : resultChildren) {
-        if ("constructor".equals(resultChild.getName())) {
-          processConstructorElement(resultChild,typeClass,resultMappings);
-        } else if ("discriminator".equals(resultChild.getName())) {
-          discriminator = processDiscriminatorElement(resultChild,typeClass);
-        } else {
-          ArrayList<ResultFlag> flags = new ArrayList<ResultFlag>();
-          if ("id".equals(resultChild.getName())) {
-            flags.add(ResultFlag.ID);
-          }
-          resultMappings.add(buildResultMappingFromContext(resultChild, 
typeClass, flags));
-        }
-      }
-    assistant.addResultMap(id, typeClass, extend, discriminator, 
resultMappings);
-  }
 
-  private void processChildrenAsResultMap(XNode resultChild) throws Exception {
-    List<String> acceptedResultMapElements = Arrays.asList(new 
String[]{"association","collection","case"});
-    for (XNode arg : resultChild.getChildren()) {
-      if (acceptedResultMapElements.contains(resultChild.getName()) && 
arg.getChildren().size() > 0) {
-        resultMapElement(arg);
+  private ResultMap resultMapElement(XNode resultMapNode) throws Exception {
+    return resultMapElement(resultMapNode, Collections.EMPTY_LIST);
+  }
+  
+  private ResultMap resultMapElement(XNode resultMapNode, List<ResultMapping> 
additionalResultMappings) throws Exception {
+    ErrorContext.instance().activity("processing " + 
resultMapNode.getValueBasedIdentifier());
+    String id = resultMapNode.getStringAttribute("id",
+        resultMapNode.getValueBasedIdentifier());
+    String type = resultMapNode.getStringAttribute("type",
+        resultMapNode.getStringAttribute("ofType",
+            resultMapNode.getStringAttribute("resultType",
+                resultMapNode.getStringAttribute("javaType"))));
+    System.out.println(id + " " + type);
+    String extend = resultMapNode.getStringAttribute("extends");
+    Class typeClass = resolveClass(type);
+    Discriminator discriminator = null;
+    List<ResultMapping> resultMappings = new ArrayList<ResultMapping>();
+    resultMappings.addAll(additionalResultMappings);
+    List<XNode> resultChildren = resultMapNode.getChildren();
+    for (XNode resultChild : resultChildren) {
+      if ("constructor".equals(resultChild.getName())) {
+        processConstructorElement(resultChild, typeClass, resultMappings);
+      } else if ("discriminator".equals(resultChild.getName())) {
+        discriminator = processDiscriminatorElement(resultChild, typeClass, 
resultMappings);
+      } else {
+        ArrayList<ResultFlag> flags = new ArrayList<ResultFlag>();
+        if ("id".equals(resultChild.getName())) {
+          flags.add(ResultFlag.ID);
+        }
+        resultMappings.add(buildResultMappingFromContext(resultChild, 
typeClass, flags));
       }
     }
+    return assistant.addResultMap(id, typeClass, extend, discriminator, 
resultMappings);
   }
 
   private void processConstructorElement(XNode resultChild, Class resultType, 
List<ResultMapping> resultMappings) throws Exception {
@@ -155,7 +153,7 @@
     }
   }
 
-  private Discriminator processDiscriminatorElement(XNode context, Class 
resultType) throws Exception {
+  private Discriminator processDiscriminatorElement(XNode context, Class 
resultType, List<ResultMapping> resultMappings) throws Exception {
     String column = context.getStringAttribute("column");
     String javaType = context.getStringAttribute("javaType");
     String jdbcType = context.getStringAttribute("jdbcType");
@@ -163,11 +161,11 @@
     Class javaTypeClass = resolveClass(javaType);
     Class typeHandlerClass = resolveClass(typeHandler);
     JdbcType jdbcTypeEnum = resolveJdbcType(jdbcType);
-    Map<String, String> discriminatorMap = new HashMap<String,String>();
+    Map<String, String> discriminatorMap = new HashMap<String, String>();
     for (XNode caseChild : context.getChildren()) {
-      processChildrenAsResultMap(caseChild);
       String value = caseChild.getStringAttribute("value");
-      String resultMap = caseChild.getStringAttribute("resultMap");
+      String resultMap = caseChild.getStringAttribute("resultMap",
+          processNestedResultMappings(caseChild, resultMappings));
       discriminatorMap.put(value, resultMap);
     }
     return assistant.buildDiscriminator(resultType, column, javaTypeClass, 
jdbcTypeEnum, typeHandlerClass, discriminatorMap);
@@ -187,13 +185,14 @@
     }
   }
 
-  private ResultMapping buildResultMappingFromContext(XNode context, Class 
resultType, ArrayList<ResultFlag> flags) {
+  private ResultMapping buildResultMappingFromContext(XNode context, Class 
resultType, ArrayList<ResultFlag> flags) throws Exception {
     String property = context.getStringAttribute("property");
     String column = context.getStringAttribute("column");
     String javaType = context.getStringAttribute("javaType");
     String jdbcType = context.getStringAttribute("jdbcType");
     String nestedSelect = context.getStringAttribute("select");
-    String nestedResultMap = context.getStringAttribute("resultMap");
+    String nestedResultMap = context.getStringAttribute("resultMap",
+        processNestedResultMappings(context, Collections.EMPTY_LIST));
     String typeHandler = context.getStringAttribute("typeHandler");
     Class javaTypeClass = resolveClass(javaType);
     Class typeHandlerClass = resolveClass(typeHandler);
@@ -201,6 +200,18 @@
     return assistant.buildResultMapping(resultType, property, column, 
javaTypeClass, jdbcTypeEnum, nestedSelect, nestedResultMap, typeHandlerClass, 
flags);
   }
 
+  private String processNestedResultMappings(XNode context, 
List<ResultMapping> resultMappings) throws Exception {
+    if ("association".equals(context.getName())
+        || "collection".equals(context.getName())
+        || "case".equals(context.getName())) {
+      if (context.getStringAttribute("select") == null) {
+        ResultMap resultMap = resultMapElement(context,resultMappings);
+        return resultMap.getId();
+      }
+    }
+    return null;
+  }
+
   private void bindMapperForNamespace() {
     String namespace = assistant.getCurrentNamespace();
     if (namespace != null) {

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/xml/ibatis-3-mapper.dtd
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/xml/ibatis-3-mapper.dtd?rev=780313&r1=780312&r2=780313&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/xml/ibatis-3-mapper.dtd
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/builder/xml/ibatis-3-mapper.dtd
 Sat May 30 19:54:21 2009
@@ -85,6 +85,7 @@
 property CDATA #REQUIRED
 column CDATA #IMPLIED
 javaType CDATA #IMPLIED
+ofType CDATA #IMPLIED
 jdbcType CDATA #IMPLIED
 select CDATA #IMPLIED
 resultMap CDATA #IMPLIED
@@ -114,7 +115,7 @@
 <!ATTLIST case
 value CDATA #REQUIRED
 resultMap CDATA #IMPLIED 
-javaType CDATA #IMPLIED
+resultType CDATA #IMPLIED
 >
 
 <!ELEMENT property EMPTY>

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java?rev=780313&r1=780312&r2=780313&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java
 Sat May 30 19:54:21 2009
@@ -129,7 +129,7 @@
 
   private Object loadResultObject(ResultSet rs, ResultMap rm, 
Reference<Boolean> foundValues) throws SQLException {
     if (rm.getType() == null) {
-      throw new ExecutorException("The result class was null when trying to 
get results for ResultMap.");
+      throw new ExecutorException("The result class was null when trying to 
get results for ResultMap " + rm.getId());
     }
 
     Object resultObject = createResultObject(rs, rm);
@@ -318,7 +318,7 @@
                   metaObject.setValue(propertyName, nestedResultObject);
                 }
               }
-            } catch (SQLException e) {
+            } catch (Exception e) {
               throw new ExecutorException("Error getting nested result map 
values for '" + resultMapping.getProperty() + "'.  Cause: " + e, e);
             }
           }

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MetaObject.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MetaObject.java?rev=780313&r1=780312&r2=780313&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MetaObject.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MetaObject.java
 Sat May 30 19:54:21 2009
@@ -208,7 +208,7 @@
         throw ExceptionUtil.unwrapThrowable(t);
       }
     } catch (Throwable t) {
-      throw new ReflectionException("Could not set property '" + 
prop.getName() + "' for " + object + ".  Cause: " + t.toString(), t);
+      throw new ReflectionException("Could not set property '" + 
prop.getName() + "' of '" + object + "' with value '"+value+"' Cause: " + 
t.toString(), t);
     }
   }
 

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/builder/MapperConfig.xml
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/builder/MapperConfig.xml?rev=780313&r1=780312&r2=780313&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/builder/MapperConfig.xml
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/builder/MapperConfig.xml
 Sat May 30 19:54:21 2009
@@ -63,7 +63,7 @@
     <mapper resource="org/apache/ibatis/builder/BlogMapper.xml"/>
     <mapper resource="org/apache/ibatis/builder/CachedAuthorMapper.xml"/>
     <mapper resource="org/apache/ibatis/builder/PostMapper.xml"/>
-    <!--<mapper resource="org/apache/ibatis/builder/NestedBlogMapper.xml"/>-->
+    <mapper resource="org/apache/ibatis/builder/NestedBlogMapper.xml"/>
   </mappers>
 
 </configuration>

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/builder/NestedBlogMapper.xml
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/builder/NestedBlogMapper.xml?rev=780313&r1=780312&r2=780313&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/builder/NestedBlogMapper.xml
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/builder/NestedBlogMapper.xml
 Sat May 30 19:54:21 2009
@@ -17,18 +17,18 @@
       <result property="bio" column="author_bio"/>
       <result property="favouriteSection" column="author_favourite_section"/>
     </association>
-    <collection property="posts" javaType="domain.blog.Post">
+    <collection property="posts" ofType="domain.blog.Post">
       <id property="id" column="post_id"/>
       <result property="subject" column="post_subject"/>
-      <association property="author" column="post_author_id" 
resultMap="joinedAuthor"/>
-      <collection property="comments" column="post_id" 
resultMap="joinedComment">
+      <association property="author" column="post_author_id" 
javaType="domain.blog.Author"/>
+      <collection property="comments" column="post_id" 
ofType="domain.blog.Comment" >
         <id property="id" column="comment_id"/>
       </collection>
-      <collection property="tags" column="post_id" resultMap="joinedTag">
+      <collection property="tags" column="post_id" ofType="domain.blog.Tag" >
         <id property="id" column="tag_id"/>
       </collection>
       <discriminator javaType="int" column="draft">
-        <case value="1" javaType="domain.blog.DraftPost"/>
+        <case value="1" resultType="domain.blog.DraftPost"/>
       </discriminator>
     </collection>
   </resultMap>

Modified: 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/session/SqlSessionTest.java
URL: 
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/session/SqlSessionTest.java?rev=780313&r1=780312&r2=780313&view=diff
==============================================================================
--- 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/session/SqlSessionTest.java
 (original)
+++ 
ibatis/trunk/java/ibatis-3/ibatis-3-core/src/test/java/org/apache/ibatis/session/SqlSessionTest.java
 Sat May 30 19:54:21 2009
@@ -220,7 +220,7 @@
     }
   }
 
-  @Test @Ignore
+  @Test 
   public void shouldSelectNestedBlogWithPostsAndAuthorUsingJoin() throws 
Exception {
     SqlSession session = sqlMapper.openSession();
     try {


Reply via email to