[#8460] Regression calling POJO setters twice from DefaultRecordMapper.MutablePOJOMapper
This commit is contained in:
parent
c70eab4fca
commit
78c4295e61
@ -179,6 +179,7 @@ import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@ -3309,7 +3310,7 @@ final class Tools {
|
||||
|
||||
@Override
|
||||
public List<Method> call() {
|
||||
List<Method> result = new ArrayList<Method>();
|
||||
Set<SourceMethod> set = new LinkedHashSet<SourceMethod>();
|
||||
|
||||
for (Method method : getInstanceMethods(type)) {
|
||||
Column column = method.getAnnotation(Column.class);
|
||||
@ -3318,7 +3319,7 @@ final class Tools {
|
||||
|
||||
// Annotated setter
|
||||
if (method.getParameterTypes().length == 1) {
|
||||
result.add(accessible(method));
|
||||
set.add(new SourceMethod(accessible(method)));
|
||||
}
|
||||
|
||||
// Annotated getter with matching setter
|
||||
@ -3336,7 +3337,7 @@ final class Tools {
|
||||
|
||||
// Setter annotation is more relevant
|
||||
if (setter.getAnnotation(Column.class) == null)
|
||||
result.add(accessible(setter));
|
||||
set.add(new SourceMethod(accessible(setter)));
|
||||
}
|
||||
catch (NoSuchMethodException ignore) {}
|
||||
}
|
||||
@ -3344,7 +3345,7 @@ final class Tools {
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return SourceMethod.methods(set);
|
||||
}
|
||||
|
||||
}, DATA_REFLECTION_CACHE_GET_ANNOTATED_SETTERS, Cache.key(type, name));
|
||||
@ -3409,7 +3410,9 @@ final class Tools {
|
||||
|
||||
@Override
|
||||
public List<Method> call() {
|
||||
List<Method> result = new ArrayList<Method>();
|
||||
|
||||
// [#8460] Prevent duplicate methods in the call hierarchy
|
||||
Set<SourceMethod> set = new LinkedHashSet<SourceMethod>();
|
||||
|
||||
// [#1942] Caching these values before the method-loop significantly
|
||||
// accerates POJO mapping
|
||||
@ -3421,16 +3424,16 @@ final class Tools {
|
||||
|
||||
if (parameterTypes.length == 1)
|
||||
if (name.equals(method.getName()))
|
||||
result.add(accessible(method));
|
||||
set.add(new SourceMethod(accessible(method)));
|
||||
else if (camelCaseLC.equals(method.getName()))
|
||||
result.add(accessible(method));
|
||||
set.add(new SourceMethod(accessible(method)));
|
||||
else if (("set" + name).equals(method.getName()))
|
||||
result.add(accessible(method));
|
||||
set.add(new SourceMethod(accessible(method)));
|
||||
else if (("set" + camelCase).equals(method.getName()))
|
||||
result.add(accessible(method));
|
||||
set.add(new SourceMethod(accessible(method)));
|
||||
}
|
||||
|
||||
return result;
|
||||
return SourceMethod.methods(set);
|
||||
}
|
||||
|
||||
}, DATA_REFLECTION_CACHE_GET_MATCHING_SETTERS, Cache.key(type, name));
|
||||
@ -3471,8 +3474,67 @@ final class Tools {
|
||||
}, DATA_REFLECTION_CACHE_GET_MATCHING_GETTER, Cache.key(type, name));
|
||||
}
|
||||
|
||||
private static final List<Method> getInstanceMethods(Class<?> type) {
|
||||
List<Method> result = new ArrayList<Method>();
|
||||
/**
|
||||
* A wrapper class that re-implements {@link Method#equals(Object)} and
|
||||
* {@link Method#hashCode()} based only on the "source signature" (name,
|
||||
* parameter types), instead of the "binary signature" (declaring class,
|
||||
* name, return type, parameter types).
|
||||
*/
|
||||
private static final class SourceMethod {
|
||||
final Method method;
|
||||
|
||||
SourceMethod(Method method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
static List<Method> methods(Collection<? extends SourceMethod> methods) {
|
||||
List<Method> result = new ArrayList<Method>(methods.size());
|
||||
|
||||
for (SourceMethod s : methods)
|
||||
result.add(s.method);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((method == null) ? 0 : method.getName().hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof SourceMethod) {
|
||||
Method other = ((SourceMethod) obj).method;
|
||||
|
||||
if (method.getName().equals(other.getName())) {
|
||||
Class<?>[] p1 = method.getParameterTypes();
|
||||
Class<?>[] p2 = other.getParameterTypes();
|
||||
|
||||
return Arrays.equals(p1, p2);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return method.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* All the public and declared methods of a type.
|
||||
* <p>
|
||||
* This method returns each method only once. Public methods are returned
|
||||
* first in the resulting set while declared methods are returned
|
||||
* afterwards, from lowest to highest type in the type hierarchy.
|
||||
*/
|
||||
private static final Set<Method> getInstanceMethods(Class<?> type) {
|
||||
Set<Method> result = new LinkedHashSet<Method>();
|
||||
|
||||
for (Method method : type.getMethods())
|
||||
if ((method.getModifiers() & Modifier.STATIC) == 0)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user