Skip to content

Commit 3111a25

Browse files
Fixed http://code.google.com/p/mybatis/issues/detail?id=180 . Modified StrictMap so that statements/fragments cannot be references by their short name when a long name is specified.
1 parent 6f932f5 commit 3111a25

File tree

11 files changed

+306
-7
lines changed

11 files changed

+306
-7
lines changed

src/main/java/org/apache/ibatis/session/Configuration.java

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public class Configuration {
7777
protected final TypeHandlerRegistry typeHandlerRegistry = new TypeHandlerRegistry();
7878
protected final TypeAliasRegistry typeAliasRegistry = new TypeAliasRegistry();
7979
protected final Map<String, MappedStatement> mappedStatements = new StrictMap<String, MappedStatement>("Mapped Statements collection");
80-
protected final Map<String, Cache> caches = new StrictMap<String, Cache>("Caches collection");
80+
protected final Map<String, Cache> caches = new CacheMap<String, Cache>("Caches collection");
8181
protected final Map<String, ResultMap> resultMaps = new StrictMap<String, ResultMap>("Result Maps collection");
8282
protected final Map<String, ParameterMap> parameterMaps = new StrictMap<String, ParameterMap>("Parameter Maps collection");
8383
protected final Map<String, KeyGenerator> keyGenerators = new StrictMap<String, KeyGenerator>("Key Generators collection");
@@ -511,26 +511,26 @@ protected void checkLocallyForDiscriminatedNestedResultMaps(ResultMap rm) {
511511
}
512512
}
513513

514-
protected static class StrictMap<J extends String, K extends Object> extends HashMap<J, K> {
514+
protected static class CacheMap<J extends String, K extends Object> extends HashMap<J, K> {
515515

516516
private String name;
517517

518-
public StrictMap(String name, int initialCapacity, float loadFactor) {
518+
public CacheMap(String name, int initialCapacity, float loadFactor) {
519519
super(initialCapacity, loadFactor);
520520
this.name = name;
521521
}
522522

523-
public StrictMap(String name, int initialCapacity) {
523+
public CacheMap(String name, int initialCapacity) {
524524
super(initialCapacity);
525525
this.name = name;
526526
}
527527

528-
public StrictMap(String name) {
528+
public CacheMap(String name) {
529529
super();
530530
this.name = name;
531531
}
532532

533-
public StrictMap(String name, Map<? extends J, ? extends K> m) {
533+
public CacheMap(String name, Map<? extends J, ? extends K> m) {
534534
super(m);
535535
this.name = name;
536536
}
@@ -579,5 +579,43 @@ public String getSubject() {
579579
}
580580
}
581581
}
582+
583+
protected static class StrictMap<J extends String, K extends Object> extends HashMap<J, K> {
582584

585+
private String name;
586+
587+
public StrictMap(String name, int initialCapacity, float loadFactor) {
588+
super(initialCapacity, loadFactor);
589+
this.name = name;
590+
}
591+
592+
public StrictMap(String name, int initialCapacity) {
593+
super(initialCapacity);
594+
this.name = name;
595+
}
596+
597+
public StrictMap(String name) {
598+
super();
599+
this.name = name;
600+
}
601+
602+
public StrictMap(String name, Map<? extends J, ? extends K> m) {
603+
super(m);
604+
this.name = name;
605+
}
606+
607+
public K put(J key, K value) {
608+
if (containsKey(key))
609+
throw new IllegalArgumentException(name + " already contains value for " + key);
610+
return super.put(key, value);
611+
}
612+
613+
public K get(Object key) {
614+
K value = super.get(key);
615+
if (value == null) {
616+
throw new IllegalArgumentException(name + " does not contain value for " + key);
617+
}
618+
return value;
619+
}
620+
}
583621
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<!DOCTYPE mapper
4+
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
5+
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
6+
7+
<mapper namespace="org.apache.ibatis.submitted.refid_resolution.Mapper">
8+
<sql id="columnList">
9+
field1, field2
10+
</sql>
11+
<select id="selectValid" resultType="map">
12+
select
13+
<include refid="columnList" />
14+
from table1
15+
</select>
16+
<select id="selectInvalid" resultType="map">
17+
select
18+
<!-- Non-existent refid with the same short name -->
19+
<include refid="noSuchMapper.columnList" />
20+
from table1
21+
</select>
22+
</mapper>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
3+
<!DOCTYPE configuration
4+
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
5+
"http://mybatis.org/dtd/mybatis-3-config.dtd">
6+
7+
<configuration>
8+
9+
<mappers>
10+
<mapper resource="org/apache/ibatis/submitted/refid_resolution/Mapper.xml" />
11+
</mappers>
12+
13+
</configuration>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.apache.ibatis.submitted.refid_resolution;
2+
3+
import java.io.Reader;
4+
5+
import org.apache.ibatis.exceptions.PersistenceException;
6+
import org.apache.ibatis.io.Resources;
7+
import org.apache.ibatis.session.SqlSessionFactory;
8+
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
9+
import org.junit.Test;
10+
11+
public class RefidResolutionTest {
12+
@Test(expected = PersistenceException.class)
13+
public void testIncludes() throws Exception {
14+
String resource = "org/apache/ibatis/submitted/refid_resolution/MapperConfig.xml";
15+
Reader reader = Resources.getResourceAsReader(resource);
16+
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
17+
SqlSessionFactory sqlSessionFactory = builder.build(reader);
18+
sqlSessionFactory.getConfiguration().getMappedStatementNames();
19+
}
20+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
3+
<!DOCTYPE configuration
4+
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
5+
"http://mybatis.org/dtd/mybatis-3-config.dtd">
6+
7+
<configuration>
8+
9+
<environments default="development">
10+
<environment id="development">
11+
<transactionManager type="JDBC">
12+
<property name="" value=""/>
13+
</transactionManager>
14+
<dataSource type="UNPOOLED">
15+
<property name="driver" value="org.hsqldb.jdbcDriver"/>
16+
<property name="url" value="jdbc:hsqldb:mem:xmlextref"/>
17+
<property name="username" value="sa"/>
18+
</dataSource>
19+
</environment>
20+
</environments>
21+
22+
<mappers>
23+
<mapper resource="org/apache/ibatis/submitted/xml_external_ref/SameIdPersonMapper.xml"/>
24+
<mapper resource="org/apache/ibatis/submitted/xml_external_ref/SameIdPetMapper.xml"/>
25+
</mappers>
26+
27+
</configuration>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package org.apache.ibatis.submitted.xml_external_ref;
2+
3+
public interface SameIdPersonMapper {
4+
Person select(Integer id);
5+
6+
Pet selectPet(Integer id);
7+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
3+
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
4+
<mapper namespace="org.apache.ibatis.submitted.xml_external_ref.SameIdPersonMapper">
5+
<cache-ref namespace="org.apache.ibatis.submitted.xml_external_ref.SameIdPetMapper" />
6+
<resultMap type="org.apache.ibatis.submitted.xml_external_ref.Person"
7+
id="personResult">
8+
<id property="id" column="person_id" />
9+
<result property="name" column="person_name" />
10+
</resultMap>
11+
<resultMap type="org.apache.ibatis.submitted.xml_external_ref.Person"
12+
id="resultWithPets" extends="personResult">
13+
<collection property="pets"
14+
ofType="org.apache.ibatis.submitted.xml_external_ref.Pet"
15+
resultMap="org.apache.ibatis.submitted.xml_external_ref.SameIdPetMapper.petResult" />
16+
</resultMap>
17+
<sql id="columns">
18+
person_id, person_name
19+
</sql>
20+
<!-- Referencing a sql fragment in another file -->
21+
<select id="select" parameterType="java.lang.Integer" resultMap="resultWithPets">
22+
SELECT
23+
<include refid="columns" />
24+
,
25+
<include
26+
refid="org.apache.ibatis.submitted.xml_external_ref.SameIdPetMapper.columns" />
27+
FROM person, pet
28+
WHERE person_id = #{id}
29+
AND person_id = owner_id
30+
ORDER BY pet_id
31+
</select>
32+
<!-- Referencing a sql fragment and a result map in another file -->
33+
<select id="selectPet" parameterType="java.lang.Integer"
34+
resultMap="org.apache.ibatis.submitted.xml_external_ref.SameIdPetMapper.petResult">
35+
SELECT
36+
<include
37+
refid="org.apache.ibatis.submitted.xml_external_ref.SameIdPetMapper.columns" />
38+
FROM pet
39+
WHERE pet_id = #{id}
40+
</select>
41+
</mapper>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package org.apache.ibatis.submitted.xml_external_ref;
2+
3+
public interface SameIdPetMapper {
4+
Pet select(Integer id);
5+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
3+
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
4+
<mapper namespace="org.apache.ibatis.submitted.xml_external_ref.SameIdPetMapper">
5+
<cache />
6+
<resultMap type="org.apache.ibatis.submitted.xml_external_ref.Pet" id="petResult">
7+
<id property="id" column="pet_id" />
8+
<result property="ownerId" column="owner_id" />
9+
<result property="name" column="pet_name" />
10+
</resultMap>
11+
<resultMap type="org.apache.ibatis.submitted.xml_external_ref.Pet" id="resultWithOwner"
12+
extends="petResult">
13+
<association property="owner" javaType="org.apache.ibatis.submitted.xml_external_ref.Person"
14+
resultMap="org.apache.ibatis.submitted.xml_external_ref.SameIdPersonMapper.personResult" />
15+
</resultMap>
16+
<sql id="columns">
17+
pet_id, owner_id, pet_name
18+
</sql>
19+
<select id="select" parameterType="java.lang.Integer" resultMap="resultWithOwner">
20+
SELECT
21+
<include refid="columns" />
22+
,
23+
<include refid="org.apache.ibatis.submitted.xml_external_ref.SameIdPersonMapper.columns" />
24+
FROM pet, person where person_id = owner_id
25+
AND pet_id = #{id}
26+
</select>
27+
</mapper>
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package org.apache.ibatis.submitted.xml_external_ref;
2+
3+
import static org.junit.Assert.*;
4+
5+
import java.io.IOException;
6+
import java.io.Reader;
7+
import java.sql.Connection;
8+
import java.sql.DriverManager;
9+
import java.sql.SQLException;
10+
11+
import org.apache.ibatis.datasource.unpooled.UnpooledDataSource;
12+
import org.apache.ibatis.io.Resources;
13+
import org.apache.ibatis.jdbc.ScriptRunner;
14+
import org.apache.ibatis.mapping.Environment;
15+
import org.apache.ibatis.session.Configuration;
16+
import org.apache.ibatis.session.SqlSession;
17+
import org.apache.ibatis.session.SqlSessionFactory;
18+
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
19+
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
20+
import org.junit.Test;
21+
22+
public class SameIdTest {
23+
24+
@Test
25+
public void testCrossReferenceXmlConfig() throws Exception {
26+
testCrossReference(getSqlSessionFactoryXmlConfig());
27+
}
28+
29+
@Test
30+
public void testCrossReferenceJavaConfig() throws Exception {
31+
testCrossReference(getSqlSessionFactoryJavaConfig());
32+
}
33+
34+
private void testCrossReference(SqlSessionFactory sqlSessionFactory) throws Exception {
35+
SqlSession sqlSession = sqlSessionFactory.openSession();
36+
try {
37+
SameIdPersonMapper personMapper = sqlSession.getMapper(SameIdPersonMapper.class);
38+
Person person = personMapper.select(1);
39+
assertEquals((Integer)1, person.getId());
40+
assertEquals(2, person.getPets().size());
41+
assertEquals((Integer)2, person.getPets().get(1).getId());
42+
43+
Pet pet = personMapper.selectPet(1);
44+
assertEquals(Integer.valueOf(1), pet.getId());
45+
46+
SameIdPetMapper petMapper = sqlSession.getMapper(SameIdPetMapper.class);
47+
Pet pet2 = petMapper.select(3);
48+
assertEquals((Integer)3, pet2.getId());
49+
assertEquals((Integer)2, pet2.getOwner().getId());
50+
} finally {
51+
sqlSession.close();
52+
}
53+
}
54+
55+
private SqlSessionFactory getSqlSessionFactoryXmlConfig() throws Exception {
56+
Reader configReader = Resources
57+
.getResourceAsReader("org/apache/ibatis/submitted/xml_external_ref/SameIdMapperConfig.xml");
58+
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configReader);
59+
configReader.close();
60+
61+
Connection conn = sqlSessionFactory.getConfiguration().getEnvironment().getDataSource().getConnection();
62+
initDb(conn);
63+
64+
return sqlSessionFactory;
65+
}
66+
67+
private SqlSessionFactory getSqlSessionFactoryJavaConfig() throws Exception {
68+
Class.forName("org.hsqldb.jdbcDriver");
69+
Connection c = DriverManager.getConnection("jdbc:hsqldb:mem:xmlextref", "sa", "");
70+
initDb(c);
71+
72+
Configuration configuration = new Configuration();
73+
Environment environment = new Environment("development", new JdbcTransactionFactory(), new UnpooledDataSource(
74+
"org.hsqldb.jdbcDriver", "jdbc:hsqldb:mem:xmlextref", null));
75+
configuration.setEnvironment(environment);
76+
77+
configuration.addMapper(SameIdPersonMapper.class);
78+
configuration.addMapper(SameIdPetMapper.class);
79+
80+
return new SqlSessionFactoryBuilder().build(configuration);
81+
}
82+
83+
private static void initDb(Connection conn) throws IOException, SQLException {
84+
try {
85+
Reader scriptReader = Resources.getResourceAsReader("org/apache/ibatis/submitted/xml_external_ref/CreateDB.sql");
86+
ScriptRunner runner = new ScriptRunner(conn);
87+
runner.setLogWriter(null);
88+
runner.setErrorLogWriter(null);
89+
runner.runScript(scriptReader);
90+
conn.commit();
91+
scriptReader.close();
92+
} finally {
93+
if (conn != null) {
94+
conn.close();
95+
}
96+
}
97+
}
98+
99+
}

0 commit comments

Comments
 (0)