From 8fba879f62baed32e15c3fa36cca972c8264193e Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Thu, 26 Mar 2020 15:42:51 +0100 Subject: [PATCH] [jOOQ/jOOQ#6598] Fixed also @ConstructorProperties mapping --- .../org/jooq/impl/DefaultRecordMapper.java | 189 ++++++++++-------- 1 file changed, 101 insertions(+), 88 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultRecordMapper.java b/jOOQ/src/main/java/org/jooq/impl/DefaultRecordMapper.java index 3bba16c3ee..fa18ea4201 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultRecordMapper.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultRecordMapper.java @@ -39,10 +39,8 @@ package org.jooq.impl; import static java.lang.Boolean.FALSE; import static java.lang.Boolean.TRUE; -import static java.util.Collections.nCopies; import static org.jooq.impl.DSL.field; import static org.jooq.impl.DSL.name; -import static org.jooq.impl.Tools.EMPTY_FIELD; import static org.jooq.impl.Tools.getAnnotatedGetter; import static org.jooq.impl.Tools.getAnnotatedMembers; import static org.jooq.impl.Tools.getAnnotatedSetters; @@ -386,7 +384,7 @@ public class DefaultRecordMapper implements RecordMapper implements RecordMapper javaConstructor = (Constructor) this.type.getConstructor(parameterTypes); - delegate = new ImmutablePOJOMapperWithParameterNames(javaConstructor, parameterNames); + delegate = new ImmutablePOJOMapperWithParameterNames(javaConstructor, parameterNames, true); return; } } @@ -466,7 +464,7 @@ public class DefaultRecordMapper implements RecordMapper 0) - delegate = new ImmutablePOJOMapperWithParameterNames(constructor, collectParameterNames(parameters)); + delegate = new ImmutablePOJOMapperWithParameterNames(constructor, collectParameterNames(parameters), supportsNesting); } @@ -487,7 +485,7 @@ public class DefaultRecordMapper implements RecordMapper 0) { - delegate = new ImmutablePOJOMapperWithParameterNames(constructor, collectParameterNames(parameters)); + delegate = new ImmutablePOJOMapperWithParameterNames(constructor, collectParameterNames(parameters), true); return; } } @@ -684,22 +682,22 @@ public class DefaultRecordMapper implements RecordMapper { - private final Callable constructor; - private final boolean useAnnotations; - private final List[] members; - private final List[] methods; - private final Map>> nested; - private final E instance; + private final Callable constructor; + private final boolean useAnnotations; + private final List[] members; + private final List[] methods; + private Map>> nestedMappers; + private Map>> nestedMappedFields; + private Map> nestedIndexLookup; + private final E instance; MutablePOJOMapper(Callable constructor, E instance) { this.constructor = constructor; this.useAnnotations = hasColumnAnnotations(configuration, type); this.members = new List[fields.length]; this.methods = new List[fields.length]; - this.nested = new HashMap<>(); this.instance = instance; - Map[]> nestedFields = new HashMap<>(); for (int i = 0; i < fields.length; i++) { Field field = fields[i]; String name = field.getName(); @@ -718,13 +716,22 @@ public class DefaultRecordMapper implements RecordMapper -1) { String prefix = name.substring(0, dot); - Field[] f = nestedFields.get(prefix); - if (f == null) { - f = nCopies(fields.length, field("")).toArray(EMPTY_FIELD); - nestedFields.put(prefix, f); + if (nestedMappedFields == null) { + this.nestedMappers = new HashMap<>(); + this.nestedMappedFields = new HashMap<>(); + this.nestedIndexLookup = new HashMap<>(); } - f[i] = field(name(name.substring(prefix.length() + 1)), field.getDataType()); + List> f = nestedMappedFields.get(prefix); + if (f == null) + nestedMappedFields.put(prefix, f = new ArrayList<>()); + + List indexes = nestedIndexLookup.get(prefix); + if (indexes == null) + nestedIndexLookup.put(prefix, indexes = new ArrayList<>()); + + f.add(field(name(name.substring(prefix.length() + 1)), field.getDataType())); + indexes.add(i); members[i] = Collections.emptyList(); methods[i] = Collections.emptyList(); @@ -738,25 +745,27 @@ public class DefaultRecordMapper implements RecordMapper[]> entry : nestedFields.entrySet()) { - String prefix = entry.getKey(); - List> list = new ArrayList<>(); + if (nestedMappedFields != null) { + for (Entry>> entry : nestedMappedFields.entrySet()) { + String prefix = entry.getKey(); + List> list = new ArrayList<>(); - for (java.lang.reflect.Field member : getMatchingMembers(configuration, type, prefix)) { - list.add(configuration - .recordMapperProvider() - .provide(new Fields<>(entry.getValue()), member.getType()) - ); + for (java.lang.reflect.Field member : getMatchingMembers(configuration, type, prefix)) { + list.add(configuration + .recordMapperProvider() + .provide(new Fields<>(entry.getValue()), member.getType()) + ); + } + + for (Method method : getMatchingSetters(configuration, type, prefix)) { + list.add(configuration + .recordMapperProvider() + .provide(new Fields<>(entry.getValue()), method.getParameterTypes()[0]) + ); + } + + nestedMappers.put(prefix, list); } - - for (Method method : getMatchingSetters(configuration, type, prefix)) { - list.add(configuration - .recordMapperProvider() - .provide(new Fields<>(entry.getValue()), method.getParameterTypes()[0]) - ); - } - - nested.put(prefix, list); } } @@ -790,21 +799,29 @@ public class DefaultRecordMapper implements RecordMapper>> entry : nested.entrySet()) { - String prefix = entry.getKey(); + if (nestedMappers != null) { + for (Entry>> entry : nestedMappers.entrySet()) { + String prefix = entry.getKey(); - for (RecordMapper mapper : entry.getValue()) { - Object value = mapper.map(record); + for (RecordMapper mapper : entry.getValue()) { + RecordImplN rec = new RecordImplN(nestedMappedFields.get(prefix)); - for (java.lang.reflect.Field member : getMatchingMembers(configuration, type, prefix)) { + List indexes = nestedIndexLookup.get(prefix); + for (int index = 0; index < indexes.size(); index++) + rec.set(index, record.get(indexes.get(index))); - // [#935] Avoid setting final fields - if ((member.getModifiers() & Modifier.FINAL) == 0) - map(value, result, member); + Object value = mapper.map(rec); + + for (java.lang.reflect.Field member : getMatchingMembers(configuration, type, prefix)) { + + // [#935] Avoid setting final fields + if ((member.getModifiers() & Modifier.FINAL) == 0) + map(value, result, member); + } + + for (Method method : getMatchingSetters(configuration, type, prefix)) + method.invoke(result, value); } - - for (Method method : getMatchingSetters(configuration, type, prefix)) - method.invoke(result, value); } } @@ -887,15 +904,15 @@ public class DefaultRecordMapper implements RecordMapper { - private final Constructor constructor; - private final Class[] parameterTypes; + private final Constructor constructor; + private final Class[] parameterTypes; private final boolean nested; private final int[] nonNestedIndexLookup; private final List[] nestedIndexLookup; private final List>[] nestedMappedFields; private final RecordMapper[] nestedMappers; - public ImmutablePOJOMapper(Constructor constructor, Class[] parameterTypes, boolean supportsNesting) { + ImmutablePOJOMapper(Constructor constructor, Class[] parameterTypes, boolean supportsNesting) { this.constructor = accessible(constructor); this.parameterTypes = parameterTypes; this.nestedMappedFields = new List[prefixes().size()]; @@ -948,16 +965,22 @@ public class DefaultRecordMapper implements RecordMapper implements RecordMapper { + private class ImmutablePOJOMapperWithParameterNames extends ImmutablePOJOMapper { - private final Constructor constructor; - private final Class[] parameterTypes; private final List propertyNames; private final boolean useAnnotations; private final List[] members; private final java.lang.reflect.Method[] methods; private final Integer[] propertyIndexes; - ImmutablePOJOMapperWithParameterNames(Constructor constructor, List propertyNames) { - this.constructor = constructor; + ImmutablePOJOMapperWithParameterNames(Constructor constructor, List propertyNames, boolean supportsNesting) { + super(constructor, constructor.getParameterTypes(), supportsNesting); + this.propertyNames = propertyNames; this.useAnnotations = hasColumnAnnotations(configuration, type); - this.parameterTypes = constructor.getParameterTypes(); this.members = new List[fields.length]; this.methods = new Method[fields.length]; this.propertyIndexes = new Integer[fields.length]; @@ -1032,37 +1057,25 @@ public class DefaultRecordMapper implements RecordMapper= 0) - parameterValues[index] = record.get(i); - } - - if (methods[i] != null) { - String name = getPropertyName(methods[i].getName()); - int index = propertyNames.indexOf(name); - - if (index >= 0) - parameterValues[index] = record.get(i); - } - } + if (index >= 0) + array[index] = value; } - Object[] converted = Convert.convert(parameterValues, parameterTypes); - return accessible(constructor).newInstance(converted); - } - catch (Exception e) { - throw new MappingException("An error ocurred when mapping record to " + type, e); + if (methods[i] != null) { + String name = getPropertyName(methods[i].getName()); + int index = propertyNames.indexOf(name); + + if (index >= 0) + array[index] = value; + } } } }