Skip to content

Commit 1d44216

Browse files
committed
Fix for issue #385.
1 parent 9c1bfa6 commit 1d44216

File tree

7 files changed

+223
-41
lines changed

7 files changed

+223
-41
lines changed

src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java

Lines changed: 38 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -449,42 +449,11 @@ private void linkToParents(ResultSet rs, ResultMapping parentMapping, Object row
449449
List<PendingRelation> parents = pendingRelations.get(parentKey);
450450
if (parents != null) {
451451
for (PendingRelation parent : parents) {
452-
if (parent != null) {
453-
final Object collectionProperty = instantiateCollectionPropertyIfAppropriate(parent.propertyMapping, parent.metaObject);
454-
if (rowValue != null) {
455-
if (collectionProperty != null) {
456-
final MetaObject targetMetaObject = configuration.newMetaObject(collectionProperty);
457-
targetMetaObject.add(rowValue);
458-
} else {
459-
parent.metaObject.setValue(parent.propertyMapping.getProperty(), rowValue);
460-
}
461-
}
462-
}
463-
}
464-
}
465-
}
466-
467-
private Object instantiateCollectionPropertyIfAppropriate(ResultMapping resultMapping, MetaObject metaObject) {
468-
final String propertyName = resultMapping.getProperty();
469-
Object propertyValue = metaObject.getValue(propertyName);
470-
if (propertyValue == null) {
471-
Class<?> type = resultMapping.getJavaType();
472-
if (type == null) {
473-
type = metaObject.getSetterType(propertyName);
474-
}
475-
try {
476-
if (objectFactory.isCollection(type)) {
477-
propertyValue = objectFactory.create(type);
478-
metaObject.setValue(propertyName, propertyValue);
479-
return propertyValue;
452+
if (parent != null && rowValue != null) {
453+
linkObjects(parent.metaObject, parent.propertyMapping, rowValue);
480454
}
481-
} catch (Exception e) {
482-
throw new ExecutorException("Error instantiating collection property for result '" + resultMapping.getProperty() + "'. Cause: " + e, e);
483455
}
484-
} else if (objectFactory.isCollection(propertyValue.getClass())) {
485-
return propertyValue;
486456
}
487-
return null;
488457
}
489458

490459
private void addPendingChildRelation(ResultSet rs, MetaObject metaResultObject, ResultMapping parentMapping) throws SQLException {
@@ -855,23 +824,18 @@ private boolean applyNestedResultMappings(ResultSetWrapper rsw, ResultMap result
855824
}
856825
if (ancestorObject != null) {
857826
if (newObject) {
858-
metaObject.setValue(resultMapping.getProperty(), ancestorObject);
827+
linkObjects(metaObject, resultMapping, ancestorObject); // issue #385
859828
}
860829
} else {
861830
rowKey = createRowKey(nestedResultMap, rsw, columnPrefix);
862831
final CacheKey combinedKey = combineKeys(rowKey, parentRowKey);
863832
Object rowValue = nestedResultObjects.get(combinedKey);
864833
boolean knownValue = (rowValue != null);
865-
final Object collectionProperty = instantiateCollectionPropertyIfAppropriate(resultMapping, metaObject);
834+
instantiateCollectionPropertyIfAppropriate(resultMapping, metaObject); // mandatory
866835
if (anyNotNullColumnHasValue(resultMapping, columnPrefix, rsw.getResultSet())) {
867836
rowValue = getRowValue(rsw, nestedResultMap, combinedKey, rowKey, columnPrefix, rowValue);
868837
if (rowValue != null && !knownValue) {
869-
if (collectionProperty != null) {
870-
final MetaObject targetMetaObject = configuration.newMetaObject(collectionProperty);
871-
targetMetaObject.add(rowValue);
872-
} else {
873-
metaObject.setValue(resultMapping.getProperty(), rowValue);
874-
}
838+
linkObjects(metaObject, resultMapping, rowValue);
875839
foundValues = true;
876840
}
877841
}
@@ -1015,4 +979,37 @@ private void createRowKeyForMap(ResultSetWrapper rsw, CacheKey cacheKey) throws
1015979
}
1016980
}
1017981

982+
private void linkObjects(MetaObject metaObject, ResultMapping resultMapping, Object rowValue) {
983+
final Object collectionProperty = instantiateCollectionPropertyIfAppropriate(resultMapping, metaObject);
984+
if (collectionProperty != null) {
985+
final MetaObject targetMetaObject = configuration.newMetaObject(collectionProperty);
986+
targetMetaObject.add(rowValue);
987+
} else {
988+
metaObject.setValue(resultMapping.getProperty(), rowValue);
989+
}
990+
}
991+
992+
private Object instantiateCollectionPropertyIfAppropriate(ResultMapping resultMapping, MetaObject metaObject) {
993+
final String propertyName = resultMapping.getProperty();
994+
Object propertyValue = metaObject.getValue(propertyName);
995+
if (propertyValue == null) {
996+
Class<?> type = resultMapping.getJavaType();
997+
if (type == null) {
998+
type = metaObject.getSetterType(propertyName);
999+
}
1000+
try {
1001+
if (objectFactory.isCollection(type)) {
1002+
propertyValue = objectFactory.create(type);
1003+
metaObject.setValue(propertyName, propertyValue);
1004+
return propertyValue;
1005+
}
1006+
} catch (Exception e) {
1007+
throw new ExecutorException("Error instantiating collection property for result '" + resultMapping.getProperty() + "'. Cause: " + e, e);
1008+
}
1009+
} else if (objectFactory.isCollection(propertyValue.getClass())) {
1010+
return propertyValue;
1011+
}
1012+
return null;
1013+
}
1014+
10181015
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.apache.ibatis.submitted.bringrags;
2+
3+
public class SimpleChildObject {
4+
5+
private String id;
6+
private SimpleObject parentSimpleObject;
7+
8+
public SimpleChildObject(String id) {
9+
this.id = id;
10+
}
11+
12+
public String getId() {
13+
return id;
14+
}
15+
16+
public SimpleObject getSimpleObject() {
17+
return parentSimpleObject;
18+
}
19+
20+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package org.apache.ibatis.submitted.bringrags;
2+
3+
public interface SimpleChildObjectMapper {
4+
SimpleChildObject getSimpleChildObjectById(String id);
5+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
Copyright 2009-2013 the original author or authors.
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
-->
17+
<!DOCTYPE mapper
18+
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
19+
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
20+
21+
<mapper namespace="org.apache.ibatis.submitted.bringrags.SimpleChildObjectMapper">
22+
23+
<select id="getSimpleChildObjectById" resultMap="SimpleChildObjectMap">
24+
SELECT SimpleChildObject.id as sco_id, SimpleObject.id as so_id FROM SimpleChildObject
25+
LEFT JOIN SimpleObject ON SimpleChildObject.simple_object_id=SimpleObject.id
26+
WHERE SimpleChildObject.id=#{id}
27+
</select>
28+
29+
<resultMap id="SimpleChildObjectMap" type="org.apache.ibatis.submitted.bringrags.SimpleChildObject">
30+
<constructor>
31+
<idArg column="sco_id" javaType="String" />
32+
</constructor>
33+
<association property="parentSimpleObject" resultMap="SimpleObjectMap" />
34+
</resultMap>
35+
36+
<resultMap id="SimpleObjectMap" type="org.apache.ibatis.submitted.bringrags.SimpleObject">
37+
<constructor>
38+
<idArg column="so_id" javaType="String" />
39+
</constructor>
40+
<collection property="simpleChildObjects" javaType="List" ofType="org.apache.ibatis.submitted.bringrags.SimpleChildObject" resultMap="SimpleChildObjectMap" />
41+
</resultMap>
42+
43+
</mapper>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package org.apache.ibatis.submitted.bringrags;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
public class SimpleObject {
7+
8+
private String id;
9+
private List<SimpleChildObject> simpleChildObjects;
10+
11+
public SimpleObject(String id) {
12+
this.id = id;
13+
this.simpleChildObjects = new ArrayList<SimpleChildObject>();
14+
}
15+
16+
public String getId() {
17+
return id;
18+
}
19+
20+
public List<SimpleChildObject> getSimpleChildObjects() {
21+
return simpleChildObjects;
22+
}
23+
24+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package org.apache.ibatis.submitted.bringrags;
2+
3+
import java.io.Reader;
4+
import java.io.StringReader;
5+
import java.sql.Connection;
6+
7+
import org.apache.ibatis.io.Resources;
8+
import org.apache.ibatis.jdbc.ScriptRunner;
9+
import org.apache.ibatis.session.SqlSession;
10+
import org.apache.ibatis.session.SqlSessionFactory;
11+
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
12+
import org.junit.After;
13+
import org.junit.Assert;
14+
import org.junit.Before;
15+
import org.junit.Test;
16+
17+
public class SimpleObjectTest {
18+
private SimpleChildObjectMapper simpleChildObjectMapper;
19+
private SqlSession sqlSession;
20+
21+
@Before
22+
public void setUp() throws Exception {
23+
Reader reader = Resources.getResourceAsReader("org/apache/ibatis/submitted/bringrags/mybatis-config.xml");
24+
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
25+
reader.close();
26+
27+
sqlSession = sqlSessionFactory.openSession();
28+
Connection conn = sqlSession.getConnection();
29+
ScriptRunner runner = new ScriptRunner(conn);
30+
runner.setLogWriter(null);
31+
runner.runScript(new StringReader("DROP TABLE IF EXISTS SimpleObject;"));
32+
runner.runScript(new StringReader("DROP TABLE IF EXISTS SimpleChildObject;"));
33+
runner.runScript(new StringReader("CREATE TABLE SimpleObject (id VARCHAR(5) NOT NULL);"));
34+
runner.runScript(new StringReader("CREATE TABLE SimpleChildObject (id VARCHAR(5) NOT NULL, simple_object_id VARCHAR(5) NOT NULL);"));
35+
runner.runScript(new StringReader("INSERT INTO SimpleObject (id) values ('10000');"));
36+
runner.runScript(new StringReader("INSERT INTO SimpleChildObject (id, simple_object_id) values ('20000', '10000');"));
37+
reader.close();
38+
simpleChildObjectMapper = (SimpleChildObjectMapper) sqlSession.getMapper(SimpleChildObjectMapper.class);
39+
}
40+
41+
@After
42+
public void tearDown() throws Exception {
43+
sqlSession.close();
44+
}
45+
46+
@Test
47+
public void testGetById() throws Exception {
48+
SimpleChildObject sc = simpleChildObjectMapper.getSimpleChildObjectById("20000");
49+
Assert.assertNotNull(sc);
50+
Assert.assertNotNull(sc.getSimpleObject());
51+
}
52+
53+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<!--
3+
Copyright 2009-2013 the original author or authors.
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
-->
17+
<!DOCTYPE configuration
18+
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
19+
"http://mybatis.org/dtd/mybatis-3-config.dtd">
20+
21+
<configuration>
22+
23+
<environments default="development">
24+
<environment id="development">
25+
<transactionManager type="JDBC">
26+
<property name="" value="" />
27+
</transactionManager>
28+
<dataSource type="UNPOOLED">
29+
<property name="driver" value="org.hsqldb.jdbcDriver" />
30+
<property name="url" value="jdbc:hsqldb:mem:bringrags" />
31+
<property name="username" value="sa" />
32+
</dataSource>
33+
</environment>
34+
</environments>
35+
36+
<mappers>
37+
<mapper resource="org/apache/ibatis/submitted/bringrags/SimpleChildObjectMapper.xml" />
38+
</mappers>
39+
40+
</configuration>

0 commit comments

Comments
 (0)