[#1859] Add Setting to always fetch all record data after INSERT or UPDATE

This commit is contained in:
lukaseder 2016-03-10 16:55:47 +01:00
parent eec24dac28
commit a80d955c32
3 changed files with 50 additions and 18 deletions

View File

@ -48,9 +48,11 @@ import static org.jooq.impl.Tools.DataKey.DATA_OMIT_RETURNING_CLAUSE;
import java.math.BigInteger;
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import org.jooq.Configuration;
import org.jooq.DSLContext;
import org.jooq.Field;
import org.jooq.ForeignKey;
@ -168,12 +170,7 @@ public class TableRecordImpl<R extends TableRecord<R>> extends AbstractRecord im
// [#814] Refresh identity and/or main unique key values
// [#1002] Consider also identity columns of non-updatable records
// [#1537] Avoid refreshing identity columns on batch inserts
Collection<Field<?>> key = null;
if (!TRUE.equals(create.configuration().data(DATA_OMIT_RETURNING_CLAUSE))) {
key = getReturning();
insert.setReturning(key);
}
Collection<Field<?>> key = setReturningIfNeeded(create.configuration(), insert);
int result = insert.execute();
if (result > 0) {
@ -181,18 +178,8 @@ public class TableRecordImpl<R extends TableRecord<R>> extends AbstractRecord im
// [#1596] If insert was successful, update timestamp and/or version columns
setRecordVersionAndTimestamp(version, timestamp);
// If an insert was successful try fetching the generated IDENTITY value
if (key != null && !key.isEmpty()) {
if (insert.getReturnedRecord() != null) {
for (Field<?> field : key) {
int index = indexOrFail(fieldsRow(), field);
Object value = insert.getReturnedRecord().get(field);
values[index] = value;
originals[index] = value;
}
}
}
// [#1859] If an insert was successful try fetching the generated values
getReturningIfNeeded(insert, key);
for (Field<?> storeField : storeFields)
changed(storeField, false);
@ -203,6 +190,39 @@ public class TableRecordImpl<R extends TableRecord<R>> extends AbstractRecord im
return result;
}
final void getReturningIfNeeded(StoreQuery<R> query, Collection<Field<?>> key) {
if (key != null && !key.isEmpty()) {
R record = query.getReturnedRecord();
if (record != null) {
for (Field<?> field : key) {
int index = indexOrFail(fieldsRow(), field);
Object value = record.get(field);
values[index] = value;
originals[index] = value;
}
}
}
}
final Collection<Field<?>> setReturningIfNeeded(Configuration configuration, StoreQuery<R> query) {
Collection<Field<?>> key = null;
if (!TRUE.equals(configuration.data(DATA_OMIT_RETURNING_CLAUSE))) {
// [#1859] Return also non-key columns
if (TRUE.equals(configuration.settings().isReturnAllOnUpdatableRecord()))
key = Arrays.asList(fields());
else
key = getReturning();
query.setReturning(key);
}
return key;
}
/**
* Set a generated version and timestamp value onto this record after
* successfully storing the record.

View File

@ -54,6 +54,7 @@ import static org.jooq.impl.Tools.settings;
import java.math.BigInteger;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.List;
import org.jooq.Configuration;
@ -237,10 +238,16 @@ public class UpdatableRecordImpl<R extends UpdatableRecord<R>> extends TableReco
}
// [#1596] Check if the record was really changed in the database
// [#1859]
Collection<Field<?>> key = setReturningIfNeeded(configuration(), update);
int result = update.execute();
checkIfChanged(result, version, timestamp);
if (result > 0) {
// [#1859] If an update was successful try fetching the generated values
getReturningIfNeeded(update, key);
for (Field<?> storeField : storeFields)
changed(storeField, false);
}

View File

@ -82,6 +82,11 @@
<!-- Whether warnings should be fetched after each query execution -->
<element name="fetchWarnings" type="boolean" minOccurs="0" maxOccurs="1" default="true"/>
<!-- Whether calls to store(), insert() and update() should return all columns, not just identity columns.
Do note that only few databases support this feature. It is supported only in case the INSERT's or UPDATE's
RETURNING clause is fully supported, also for non-IDENTITY columns -->
<element name="returnAllOnUpdatableRecord" type="boolean" minOccurs="0" maxOccurs="1" default="false"/>
<!-- Whether JPA annotations should be considered by the DefaultRecordMapper.
This flag defaults to true in jOOQ 3.7 (emitting a warning when being used)