Skip to content

Commit a2cf7d4

Browse files
committed
#581 Type parameter resolution should work on fields as well.
1 parent d654139 commit a2cf7d4

File tree

9 files changed

+68
-6
lines changed

9 files changed

+68
-6
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,14 +275,16 @@ private void addFields(Class<?> clazz) {
275275
private void addSetField(Field field) {
276276
if (isValidPropertyName(field.getName())) {
277277
setMethods.put(field.getName(), new SetFieldInvoker(field));
278-
setTypes.put(field.getName(), field.getType());
278+
Type fieldType = TypeParameterResolver.resolveFieldType(field, type);
279+
setTypes.put(field.getName(), typeToClass(fieldType));
279280
}
280281
}
281282

282283
private void addGetField(Field field) {
283284
if (isValidPropertyName(field.getName())) {
284285
getMethods.put(field.getName(), new GetFieldInvoker(field));
285-
getTypes.put(field.getName(), field.getType());
286+
Type fieldType = TypeParameterResolver.resolveFieldType(field, type);
287+
getTypes.put(field.getName(), typeToClass(fieldType));
286288
}
287289
}
288290

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.apache.ibatis.reflection;
1717

1818
import java.lang.reflect.Array;
19+
import java.lang.reflect.Field;
1920
import java.lang.reflect.GenericArrayType;
2021
import java.lang.reflect.Method;
2122
import java.lang.reflect.ParameterizedType;
@@ -28,16 +29,30 @@
2829
*/
2930
public class TypeParameterResolver {
3031

32+
/**
33+
* @return The field type as {@link Type}. If it has type parameters in the declaration,<br>
34+
* they will be resolved to the actual runtime {@link Type}s.
35+
*/
36+
public static Type resolveFieldType(Field field, Type srcType) {
37+
Type fieldType = field.getGenericType();
38+
Class<?> declaringClass = field.getDeclaringClass();
39+
return resolveType(fieldType, srcType, declaringClass);
40+
}
41+
3142
/**
3243
* @return The return type of the method as {@link Type}. If it has type parameters in the declaration,<br>
33-
* they will be resolved to the actual runtime {@link Type}.
44+
* they will be resolved to the actual runtime {@link Type}s.
3445
*/
3546
public static Type resolveReturnType(Method method, Type srcType) {
3647
Type returnType = method.getGenericReturnType();
3748
Class<?> declaringClass = method.getDeclaringClass();
3849
return resolveType(returnType, srcType, declaringClass);
3950
}
4051

52+
/**
53+
* @return The parameter types of the method as an array of {@link Type}s. If they have type parameters in the declaration,<br>
54+
* they will be resolved to the actual runtime {@link Type}s.
55+
*/
4156
public static Type[] resolveParamTypes(Method method, Type srcType) {
4257
Type[] paramTypes = method.getGenericParameterTypes();
4358
Class<?> declaringClass = method.getDeclaringClass();

src/test/java/org/apache/ibatis/reflection/ReflectorTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,20 @@ public void shouldResolveGetterType() throws Exception {
9999
assertEquals(String.class, reflector.getGetterType("id"));
100100
}
101101

102+
@Test
103+
public void shouldResolveSetterTypeFromPrivateField() throws Exception {
104+
ReflectorFactory reflectorFactory = new DefaultReflectorFactory();
105+
Reflector reflector = reflectorFactory.findForClass(Child.class);
106+
assertEquals(String.class, reflector.getSetterType("fld"));
107+
}
108+
109+
@Test
110+
public void shouldResolveGetterTypeFromPublicField() throws Exception {
111+
ReflectorFactory reflectorFactory = new DefaultReflectorFactory();
112+
Reflector reflector = reflectorFactory.findForClass(Child.class);
113+
assertEquals(String.class, reflector.getGetterType("pubFld"));
114+
}
115+
102116
@Test
103117
public void shouldResolveParameterizedGetterType() throws Exception {
104118
ReflectorFactory reflectorFactory = new DefaultReflectorFactory();
@@ -119,6 +133,8 @@ static abstract class Parent<T extends Serializable> {
119133
protected T id;
120134
protected List<T> list;
121135
protected T[] array;
136+
private T fld;
137+
public T pubFld;
122138
public T getId() {
123139
return id;
124140
}
@@ -137,6 +153,9 @@ public T[] getArray() {
137153
public void setArray(T[] array) {
138154
this.array = array;
139155
}
156+
public T getFld() {
157+
return fld;
158+
}
140159
}
141160

142161
static class Child extends Parent<String> {

src/test/java/org/apache/ibatis/reflection/TypeParameterResolverTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import static org.junit.Assert.*;
1919

20+
import java.lang.reflect.Field;
2021
import java.lang.reflect.GenericArrayType;
2122
import java.lang.reflect.Method;
2223
import java.lang.reflect.ParameterizedType;
@@ -361,4 +362,13 @@ public void testReturn_Anonymous() throws Exception {
361362
Type result = TypeParameterResolver.resolveReturnType(method, clazz);
362363
assertEquals(Object.class, result);
363364
}
365+
366+
@Test
367+
public void testField_GenericField() throws Exception {
368+
Class<?> clazz = SubCalculator.class;
369+
Class<?> declaredClass = Calculator.class;
370+
Field field = declaredClass.getDeclaredField("fld");
371+
Type result = TypeParameterResolver.resolveFieldType(field, clazz);
372+
assertEquals(String.class, result);
373+
}
364374
}

src/test/java/org/apache/ibatis/reflection/typeparam/Calculator.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
public class Calculator<T> {
1919
protected T id;
2020

21+
private T fld;
22+
23+
protected T attribute;
24+
2125
public T getId() {
2226
return id;
2327
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ drop table users if exists;
1818

1919
create table users (
2020
id int identity,
21-
name varchar(20)
21+
name varchar(20),
22+
fld1 int,
23+
fld2 int
2224
);
2325

24-
insert into users (id, name) values(1, 'User1');
26+
insert into users (id, name, fld1, fld2) values(1, 'User1', 12, 34);

src/test/java/org/apache/ibatis/submitted/generictyperesolution/Entity.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ public class Entity<T extends Serializable> {
2222

2323
private String name;
2424

25+
private T fld1;
26+
27+
public T fld2;
28+
2529
public T getId() {
2630
return id;
2731
}
@@ -37,4 +41,8 @@ public String getName() {
3741
public void setName(String name) {
3842
this.name = name;
3943
}
44+
45+
public T getFld1() {
46+
return fld1;
47+
}
4048
}

src/test/java/org/apache/ibatis/submitted/generictyperesolution/GenericTypeResolutionTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ public void shouldGetAUser() {
5959
criteria.setId(1);
6060
User result = mapper.getUser(criteria);
6161
assertEquals("User1", result.getName());
62+
assertEquals(Integer.valueOf(12), result.getFld1());
6263
} finally {
6364
sqlSession.close();
6465
}
@@ -71,6 +72,7 @@ public void shouldInsertAUser() {
7172
Mapper mapper = sqlSession.getMapper(Mapper.class);
7273
User user = new User();
7374
user.setName("User2");
75+
user.fld2 =56;
7476
mapper.insertUser(user);
7577
User result = mapper.getUserByName("User2");
7678
assertNotNull(result);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@ public interface Mapper {
2525
@Select("select * from users where name = #{name}")
2626
User getUserByName(String name);
2727

28-
@Insert("insert into users (name) values (#{name})")
28+
@Insert("insert into users (name, fld2) values (#{name}, #{fld2})")
2929
void insertUser(User user);
3030
}

0 commit comments

Comments
 (0)