Skip to content

Commit 150db6d

Browse files
committed
java.lang.IllegalAccessException: Field is final
Signed-off-by: Ted Shaw <[email protected]>
1 parent 96d033c commit 150db6d

File tree

8 files changed

+145
-34
lines changed

8 files changed

+145
-34
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ protected boolean applyAutomaticMappings(ResultSet rs, List<String> unmappedColu
346346
}
347347
}
348348
final String property = metaObject.findProperty(propertyName, configuration.isMapUnderscoreToCamelCase());
349-
if (property != null) {
349+
if (property != null &&metaObject.hasSetter(property) ) {
350350
final Class<?> propertyType = metaObject.getSetterType(property);
351351
if (typeHandlerRegistry.hasTypeHandler(propertyType)) {
352352
final TypeHandler<?> typeHandler = resultColumnCache.getTypeHandler(propertyType, columnName);

src/main/java/org/apache/ibatis/reflection/Reflector.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.lang.reflect.Constructor;
1919
import java.lang.reflect.Field;
2020
import java.lang.reflect.Method;
21+
import java.lang.reflect.Modifier;
2122
import java.lang.reflect.ReflectPermission;
2223
import java.util.ArrayList;
2324
import java.util.Collection;
@@ -224,10 +225,12 @@ private void addFields(Class<?> clazz) {
224225
// Ignored. This is only a final precaution, nothing we can do.
225226
}
226227
}
227-
if (field.isAccessible()) {
228-
if (!setMethods.containsKey(field.getName())) {
229-
// issue 379 - removed the check for final because JDK 1.5 allows
230-
// modification of final fields through reflection (JSR-133). (JGB)
228+
int modifier=field.getModifiers();
229+
// issue 379 - removed the check for final because JDK 1.5 allows
230+
// modification of final fields through reflection (JSR-133). (JGB)
231+
// allow final but not final static
232+
if (field.isAccessible() && !(Modifier.isFinal(modifier) && Modifier.isStatic(modifier))) {
233+
if (!setMethods.containsKey(field.getName())) {
231234
addSetField(field);
232235
}
233236
if (!getMethods.containsKey(field.getName())) {
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright 2013 MyBatis.org.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.apache.ibatis.submitted.automapping;
17+
18+
public class Article {
19+
public final Integer version=0;
20+
}

src/test/java/org/apache/ibatis/submitted/automapping/AutomappingTest.java

Lines changed: 61 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717

1818
import java.io.Reader;
1919
import java.sql.Connection;
20+
import java.util.List;
2021

2122
import org.apache.ibatis.io.Resources;
2223
import org.apache.ibatis.jdbc.ScriptRunner;
24+
import org.apache.ibatis.session.AutoMappingBehavior;
2325
import org.apache.ibatis.session.SqlSession;
2426
import org.apache.ibatis.session.SqlSessionFactory;
2527
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
@@ -29,36 +31,67 @@
2931

3032
public class AutomappingTest {
3133

32-
private static SqlSessionFactory sqlSessionFactory;
34+
private static SqlSessionFactory sqlSessionFactory;
3335

34-
@BeforeClass
35-
public static void setUp() throws Exception {
36-
// create a SqlSessionFactory
37-
Reader reader = Resources.getResourceAsReader("org/apache/ibatis/submitted/automapping/mybatis-config.xml");
38-
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
39-
reader.close();
36+
@BeforeClass
37+
public static void setUp() throws Exception {
38+
// create a SqlSessionFactory
39+
Reader reader = Resources.getResourceAsReader("org/apache/ibatis/submitted/automapping/mybatis-config.xml");
40+
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
41+
reader.close();
4042

41-
// populate in-memory database
42-
SqlSession session = sqlSessionFactory.openSession();
43-
Connection conn = session.getConnection();
44-
reader = Resources.getResourceAsReader("org/apache/ibatis/submitted/automapping/CreateDB.sql");
45-
ScriptRunner runner = new ScriptRunner(conn);
46-
runner.setLogWriter(null);
47-
runner.runScript(reader);
48-
reader.close();
49-
session.close();
50-
}
43+
// populate in-memory database
44+
SqlSession session = sqlSessionFactory.openSession();
45+
Connection conn = session.getConnection();
46+
reader = Resources.getResourceAsReader("org/apache/ibatis/submitted/automapping/CreateDB.sql");
47+
ScriptRunner runner = new ScriptRunner(conn);
48+
runner.setLogWriter(null);
49+
runner.runScript(reader);
50+
reader.close();
51+
session.close();
52+
}
5153

52-
@Test
53-
public void shouldGetAUser() {
54-
SqlSession sqlSession = sqlSessionFactory.openSession();
55-
try {
56-
Mapper mapper = sqlSession.getMapper(Mapper.class);
57-
User user = mapper.getUser(1);
58-
Assert.assertEquals("User1", user.getName());
59-
} finally {
60-
sqlSession.close();
61-
}
62-
}
54+
@Test
55+
public void shouldGetAUser() {
56+
SqlSession sqlSession = sqlSessionFactory.openSession();
57+
try {
58+
Mapper mapper = sqlSession.getMapper(Mapper.class);
59+
User user = mapper.getUser(1);
60+
Assert.assertEquals("User1", user.getName());
61+
} finally {
62+
sqlSession.close();
63+
}
64+
}
6365

66+
@Test
67+
public void shouldGetBooks() {
68+
//set automapping to default partial
69+
sqlSessionFactory.getConfiguration().setAutoMappingBehavior(AutoMappingBehavior.PARTIAL);
70+
SqlSession sqlSession = sqlSessionFactory.openSession();
71+
try {
72+
Mapper mapper = sqlSession.getMapper(Mapper.class);
73+
//no errors throw
74+
List<Book> books = mapper.getBooks();
75+
Assert.assertTrue("should return results,no errors throw", !books.isEmpty());
76+
} finally {
77+
sqlSession.close();
78+
}
79+
}
80+
81+
@Test
82+
public void shouldUpdateFinalField() {
83+
//set automapping to default partial
84+
sqlSessionFactory.getConfiguration().setAutoMappingBehavior(AutoMappingBehavior.PARTIAL);
85+
SqlSession sqlSession = sqlSessionFactory.openSession();
86+
try {
87+
Mapper mapper = sqlSession.getMapper(Mapper.class);
88+
Article article = mapper.getArticle();
89+
//Java Language Specification 17.5.3 Subsequent Modification of Final Fields
90+
//http://docs.oracle.com/javase/specs/jls/se5.0/html/memory.html#17.5.3
91+
//The final field should be updated in mapping
92+
Assert.assertTrue("should update version in mapping", article.version > 0);
93+
} finally {
94+
sqlSession.close();
95+
}
96+
}
6497
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright 2013 MyBatis.org.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.apache.ibatis.submitted.automapping;
17+
18+
public class Book {
19+
public static final Integer version=0;
20+
private String name;
21+
22+
public String getName() {
23+
return name;
24+
}
25+
26+
public void setName(String name) {
27+
this.name = name;
28+
}
29+
30+
}

src/test/java/org/apache/ibatis/submitted/automapping/CreateDB.sql

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,18 @@
1616

1717
drop table users if exists;
1818

19+
drop table books if exists;
20+
1921
create table users (
2022
id int,
2123
name varchar(20)
2224
);
2325

26+
create table books (
27+
version int,
28+
name varchar(20)
29+
);
30+
2431
insert into users (id, name) values(1, 'User1');
32+
33+
insert into books (version, name) values(99, 'Learn Java');

src/test/java/org/apache/ibatis/submitted/automapping/Mapper.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,13 @@
1515
*/
1616
package org.apache.ibatis.submitted.automapping;
1717

18+
import java.util.List;
19+
1820
public interface Mapper {
1921

2022
User getUser(Integer id);
2123

24+
List<Book> getBooks();
25+
26+
Article getArticle();
2227
}

src/test/java/org/apache/ibatis/submitted/automapping/Mapper.xml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,16 @@
2626

2727
<resultMap type="org.apache.ibatis.submitted.automapping.User" id="result" autoMapping="true">
2828
</resultMap>
29-
29+
30+
<resultMap type="org.apache.ibatis.submitted.automapping.Book" id="bookResult">
31+
<result property="name" column="name"/>
32+
</resultMap>
33+
34+
<select id="getBooks" resultMap="bookResult">
35+
select version,name from books
36+
</select>
37+
38+
<select id="getArticle" resultType="org.apache.ibatis.submitted.automapping.Article">
39+
select 9 as version from INFORMATION_SCHEMA.SYSTEM_USERS
40+
</select>
3041
</mapper>

0 commit comments

Comments
 (0)