Skip to content

Commit afdbb67

Browse files
committed
Fixed issues with complicated scenarios pointed out by @kazuki43zoo
1 parent f75be73 commit afdbb67

File tree

2 files changed

+32
-5
lines changed

2 files changed

+32
-5
lines changed

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,14 +154,19 @@ private void resolveSetterConflicts(Map<String, List<Method>> conflictingSetters
154154
for (String propName : conflictingSetters.keySet()) {
155155
List<Method> setters = conflictingSetters.get(propName);
156156
Class<?> getterType = getTypes.get(propName);
157+
boolean isGetterAmbiguous = getMethods.get(propName) instanceof AmbiguousMethodInvoker;
158+
boolean isSetterAmbiguous = false;
157159
Method match = null;
158160
for (Method setter : setters) {
159-
if (setter.getParameterTypes()[0].equals(getterType)) {
161+
if (!isGetterAmbiguous && setter.getParameterTypes()[0].equals(getterType)) {
160162
// should be the best match
161163
match = setter;
162164
break;
163165
}
164-
match = pickBetterSetter(match, setter, propName);
166+
if (!isSetterAmbiguous) {
167+
match = pickBetterSetter(match, setter, propName);
168+
isSetterAmbiguous = match == null;
169+
}
165170
}
166171
if (match != null) {
167172
addSetMethod(propName, match);

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

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ class BeanClass {
198198
public void setProp1(String arg) {}
199199
public void setProp2(String arg) {}
200200
public void setProp2(Integer arg) {}
201+
public void setProp2(boolean arg) {}
201202
}
202203
ReflectorFactory reflectorFactory = new DefaultReflectorFactory();
203204
Reflector reflector = reflectorFactory.findForClass(BeanClass.class);
@@ -218,9 +219,9 @@ public void setProp2(Integer arg) {}
218219
Object[] param = String.class.equals(paramType)? new String[]{"x"} : new Integer[]{1};
219220
when(ambiguousInvoker).invoke(new BeanClass(), param);
220221
then(caughtException()).isInstanceOf(ReflectionException.class)
221-
.hasMessageContaining("Ambiguous setters defined for property 'prop2' in class '" + BeanClass.class.getName() + "' with types")
222-
.hasMessageContaining("java.lang.String")
223-
.hasMessageContaining("java.lang.Integer");
222+
.hasMessageMatching(
223+
"Ambiguous setters defined for property 'prop2' in class '" + BeanClass.class.getName().replace("$", "\\$")
224+
+ "' with types '(java.lang.String|java.lang.Integer|boolean)' and '(java.lang.String|java.lang.Integer|boolean)'\\.");
224225
}
225226

226227
@Test
@@ -300,4 +301,25 @@ public void setBool(boolean bool) {}
300301
Reflector reflector = reflectorFactory.findForClass(Bean.class);
301302
assertTrue((Boolean)reflector.getGetInvoker("bool").invoke(new Bean(), new Byte[0]));
302303
}
304+
305+
@Test
306+
void shouldIgnoreBestMatchSetterIfGetterIsAmbiguous() throws Exception {
307+
@SuppressWarnings("unused")
308+
class Bean {
309+
public Integer isBool() {return Integer.valueOf(1);}
310+
public Integer getBool() {return Integer.valueOf(2);}
311+
public void setBool(boolean bool) {}
312+
public void setBool(Integer bool) {}
313+
}
314+
ReflectorFactory reflectorFactory = new DefaultReflectorFactory();
315+
Reflector reflector = reflectorFactory.findForClass(Bean.class);
316+
Class<?> paramType = reflector.getSetterType("bool");
317+
Object[] param = boolean.class.equals(paramType) ? new Boolean[] { true } : new Integer[] { 1 };
318+
Invoker ambiguousInvoker = reflector.getSetInvoker("bool");
319+
when(ambiguousInvoker).invoke(new Bean(), param);
320+
then(caughtException()).isInstanceOf(ReflectionException.class)
321+
.hasMessageMatching(
322+
"Ambiguous setters defined for property 'bool' in class '" + Bean.class.getName().replace("$", "\\$")
323+
+ "' with types '(java.lang.Integer|boolean)' and '(java.lang.Integer|boolean)'\\.");
324+
}
303325
}

0 commit comments

Comments
 (0)