[#2836] Bad values are stored in record when projecting "ambiguous" column names into a generated record

This commit is contained in:
Lukas Eder 2014-02-05 14:19:00 +01:00
parent 5641601f3f
commit c14863a4af
2 changed files with 67 additions and 36 deletions

View File

@ -522,48 +522,53 @@ abstract class AbstractRecord extends AbstractStore implements Record {
}
@Override
public final <R extends Record> R into(final Table<R> table) {
return Utils.newRecord(table, configuration())
.operate(new RecordOperation<R, MappingException>() {
public final <R extends Record> R into(Table<R> table) {
return Utils.newRecord(table, configuration()).operate(new RecordCopyOperation<R>());
}
@Override
public R operate(R record) throws MappingException {
try {
for (Field<?> targetField : table.fields()) {
Field<?> sourceField = field(targetField);
final <R extends Record> R intoRecord(Class<R> type) {
return Utils.newRecord(type, fields(), configuration()).operate(new RecordCopyOperation<R>());
}
if (sourceField != null) {
Utils.setValue(record, targetField, AbstractRecord.this, sourceField);
private class RecordCopyOperation<R extends Record> implements RecordOperation<R, MappingException> {
@Override
public R operate(R record) throws MappingException {
try {
for (Field<?> targetField : record.fields()) {
Field<?> sourceField = field(targetField);
if (sourceField != null) {
Utils.setValue(record, targetField, AbstractRecord.this, sourceField);
}
}
// [#1522] If the primary key has been fully fetched, then changed
// flags should all be reset in order for the returned record to be
// updatable using store()
if (record instanceof AbstractRecord) {
UniqueKey<?> key = ((AbstractRecord) record).getPrimaryKey();
if (key != null) {
boolean isKeySet = true;
for (Field<?> field : key.getFields()) {
isKeySet = isKeySet && (field(field) != null);
}
if (isKeySet) {
record.changed(false);
}
}
// [#1522] If the primary key has been fully fetched, then changed
// flags should all be reset in order for the returned record to be
// updatable using store()
if (record instanceof AbstractRecord) {
UniqueKey<?> key = ((AbstractRecord) record).getPrimaryKey();
if (key != null) {
boolean isKeySet = true;
for (Field<?> field : key.getFields()) {
isKeySet = isKeySet && (field(field) != null);
}
if (isKeySet) {
record.changed(false);
}
}
}
return record;
// All reflection exceptions are intercepted
}
catch (Exception e) {
throw new MappingException("An error ocurred when mapping record to " + table, e);
}
return record;
// All reflection exceptions are intercepted
}
});
catch (Exception e) {
throw new MappingException("An error ocurred when mapping record to " + record, e);
}
}
}
@Override

View File

@ -235,6 +235,12 @@ public class DefaultRecordMapper<R extends Record, E> implements RecordMapper<R,
return;
}
// [#2989] [#2836] Records are mapped
if (AbstractRecord.class.isAssignableFrom(type)) {
delegate = (RecordMapper<R, E>) new RecordToRecordMapper();
return;
}
// [#1340] Allow for using non-public default constructors
try {
delegate = new MutablePOJOMapper(type.getDeclaredConstructor());
@ -352,6 +358,26 @@ public class DefaultRecordMapper<R extends Record, E> implements RecordMapper<R,
}
}
/**
* Convert a record into another record type.
*/
private class RecordToRecordMapper implements RecordMapper<R, AbstractRecord> {
@Override
public final AbstractRecord map(R record) {
try {
if (record instanceof AbstractRecord) {
return ((AbstractRecord) record).intoRecord((Class<AbstractRecord>) type);
}
throw new MappingException("Cannot map record " + record + " to type " + type);
}
catch (Exception e) {
throw new MappingException("An error ocurred when mapping record to " + type, e);
}
}
}
/**
* Convert a record into a mutable POJO type
* <p>