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 {