diff --git a/jOOQ/src/main/java/org/jooq/impl/ResultImpl.java b/jOOQ/src/main/java/org/jooq/impl/ResultImpl.java index 826a93680d..98b88e35a9 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ResultImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ResultImpl.java @@ -67,9 +67,9 @@ import org.jooq.Field; import org.jooq.Record; import org.jooq.RecordHandler; import org.jooq.RecordMapper; +import org.jooq.RecordType; import org.jooq.Result; import org.jooq.Row; -import org.jooq.RecordType; import org.jooq.Table; import org.jooq.exception.InvalidResultException; import org.jooq.tools.Convert; @@ -800,10 +800,10 @@ class ResultImpl implements Result, AttachableInternal { for (R record : this) { @SuppressWarnings({ "rawtypes", "unchecked" }) - Record key = new RecordImpl(keys); + RecordImpl key = new RecordImpl(keys); for (Field field : keys) { - Utils.setValue(key, field, record, field); + Utils.copyValue(key, field, record, field); } if (map.put(key, record) != null) { @@ -909,10 +909,10 @@ class ResultImpl implements Result, AttachableInternal { for (R record : this) { @SuppressWarnings({ "rawtypes", "unchecked" }) - Record key = new RecordImpl(keys); + RecordImpl key = new RecordImpl(keys); for (Field field : keys) { - Utils.setValue(key, field, record, field); + Utils.copyValue(key, field, record, field); } Result result = map.get(key); @@ -961,10 +961,10 @@ class ResultImpl implements Result, AttachableInternal { for (R record : this) { @SuppressWarnings({ "rawtypes", "unchecked" }) - Record key = new RecordImpl(keys); + RecordImpl key = new RecordImpl(keys); for (Field field : keys) { - Utils.setValue(key, field, record, field); + Utils.copyValue(key, field, record, field); } List list = map.get(key); diff --git a/jOOQ/src/main/java/org/jooq/impl/Utils.java b/jOOQ/src/main/java/org/jooq/impl/Utils.java index 58a3199c9b..b281691a63 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Utils.java +++ b/jOOQ/src/main/java/org/jooq/impl/Utils.java @@ -1171,6 +1171,19 @@ final class Utils { target.setValue(targetField, targetField.getDataType().convert(value)); } + /** + * [#2591] Type-safely copy a value from one record to another, preserving flags. + */ + static final void copyValue(AbstractRecord target, Field targetField, Record source, Field sourceField) { + Value value = new Value( + targetField.getDataType().convert(source.getValue(sourceField)), + targetField.getDataType().convert(source.original(sourceField)), + source.changed(sourceField) + ); + + target.setValue(targetField, value); + } + /** * Map a {@link Schema} according to the configured {@link org.jooq.SchemaMapping} */ diff --git a/jOOQ/src/main/java/org/jooq/impl/Value.java b/jOOQ/src/main/java/org/jooq/impl/Value.java index 0886a5382e..5fe9d237b7 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Value.java +++ b/jOOQ/src/main/java/org/jooq/impl/Value.java @@ -51,8 +51,13 @@ class Value implements Serializable { private boolean isChanged; Value(T value) { - this.original = value; + this(value, value, false); + } + + Value(T value, T original, boolean isChanged) { this.value = value; + this.original = original; + this.isChanged = isChanged; } final T getValue() {