[jOOQ/jOOQ#5394] Add a way to load POJOs into Records without setting all the changed flags to true
This commit is contained in:
parent
34b560bf82
commit
a70b920c2f
@ -621,6 +621,12 @@ public class MetaExtensions {
|
||||
setRecordClass(o);
|
||||
}
|
||||
|
||||
public void recordTypeClass(Action<MatcherRuleExtension> action) {
|
||||
MatcherRuleExtension o = objects.newInstance(MatcherRuleExtension.class, objects);
|
||||
action.execute(o);
|
||||
setRecordTypeClass(o);
|
||||
}
|
||||
|
||||
public void interfaceClass(Action<MatcherRuleExtension> action) {
|
||||
MatcherRuleExtension o = objects.newInstance(MatcherRuleExtension.class, objects);
|
||||
action.execute(o);
|
||||
|
||||
@ -456,6 +456,13 @@ fun MatchersUDTType.recordClass(block: MatcherRule.() -> Unit) {
|
||||
block(recordClass)
|
||||
}
|
||||
|
||||
fun MatchersUDTType.recordTypeClass(block: MatcherRule.() -> Unit) {
|
||||
if (recordTypeClass == null)
|
||||
recordTypeClass = MatcherRule()
|
||||
|
||||
block(recordTypeClass)
|
||||
}
|
||||
|
||||
fun MatchersUDTType.interfaceClass(block: MatcherRule.() -> Unit) {
|
||||
if (interfaceClass == null)
|
||||
interfaceClass = MatcherRule()
|
||||
|
||||
@ -37,6 +37,8 @@
|
||||
*/
|
||||
package org.jooq;
|
||||
|
||||
import org.jooq.conf.Settings;
|
||||
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
// ...
|
||||
@ -339,9 +341,11 @@ public interface InsertSetStep<R extends Record> {
|
||||
* Set values in the <code>INSERT</code> statement.
|
||||
* <p>
|
||||
* This is the same as calling {@link #set(Map)} with the argument record
|
||||
* treated as a <code>Map<Field<?>, Object></code>, except that the
|
||||
* {@link Record#touched()} flags are taken into consideration in order to
|
||||
* update only touched values.
|
||||
* treated as a <code>Map<Field<?>, Object></code>, except that
|
||||
* the {@link Record#touched()} flags (or {@link Record#modified()} flags,
|
||||
* depending on the query's {@link Settings#getRecordDirtyTracking()}
|
||||
* configuration) are taken into consideration in order to update only
|
||||
* touched (or modified) values.
|
||||
*
|
||||
* @see #set(Map)
|
||||
*/
|
||||
|
||||
@ -56,6 +56,8 @@ import static org.jooq.SQLDialect.POSTGRES;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.jooq.conf.Settings;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@ -153,9 +155,11 @@ public interface MergeMatchedSetStep<R extends Record> {
|
||||
* statement's <code>WHEN MATCHED</code> clause.
|
||||
* <p>
|
||||
* This is the same as calling {@link #set(Map)} with the argument record
|
||||
* treated as a <code>Map<Field<?>, Object></code>, except that the
|
||||
* {@link Record#touched()} flags are taken into consideration in order to
|
||||
* update only touched values.
|
||||
* treated as a <code>Map<Field<?>, Object></code>, except that
|
||||
* the {@link Record#touched()} flags (or {@link Record#modified()} flags,
|
||||
* depending on the query's {@link Settings#getRecordDirtyTracking()}
|
||||
* configuration) are taken into consideration in order to update only
|
||||
* touched (or modified) values.
|
||||
*
|
||||
* @see #set(Map)
|
||||
*/
|
||||
|
||||
@ -739,7 +739,9 @@ public interface Record extends Fields, Attachable, Comparable<Record>, Formatta
|
||||
* from the database.
|
||||
* <p>
|
||||
* When a record is {@link #modified()}, then it has always been
|
||||
* {@link #touched()} as well.
|
||||
* {@link #touched()} as well. Unlike the {@link #touched()} property, this
|
||||
* property cannot be set and is derived only from the comparison between
|
||||
* this record and the {@link #original()} record.
|
||||
*
|
||||
* @see #original()
|
||||
* @see #modified(Field)
|
||||
@ -749,11 +751,13 @@ public interface Record extends Fields, Attachable, Comparable<Record>, Formatta
|
||||
boolean modified();
|
||||
|
||||
/**
|
||||
* Check if a field's value has been modified since the record was created or
|
||||
* fetched from the database, using {@link #field(Field)} for lookup.
|
||||
* Check if a field's value has been modified since the record was created
|
||||
* or fetched from the database, using {@link #field(Field)} for lookup.
|
||||
* <p>
|
||||
* When a record is {@link #modified()}, then it has always been
|
||||
* {@link #touched()} as well.
|
||||
* {@link #touched()} as well. Unlike the {@link #touched(Field)} property,
|
||||
* this property cannot be set and is derived only from the comparison
|
||||
* between #get(Field) and {@link #original(Field)} values.
|
||||
*
|
||||
* @see #modified()
|
||||
* @see #original(Field)
|
||||
@ -761,11 +765,13 @@ public interface Record extends Fields, Attachable, Comparable<Record>, Formatta
|
||||
boolean modified(Field<?> field);
|
||||
|
||||
/**
|
||||
* Check if a field's value has been modified since the record was created or
|
||||
* fetched from the database, using {@link #field(int)} for lookup.
|
||||
* Check if a field's value has been modified since the record was created
|
||||
* or fetched from the database, using {@link #field(int)} for lookup.
|
||||
* <p>
|
||||
* When a record is {@link #modified()}, then it has always been
|
||||
* {@link #touched()} as well.
|
||||
* {@link #touched()} as well. Unlike the {@link #touched(int)} property,
|
||||
* this property cannot be set and is derived only from the comparison
|
||||
* between #get(int) and {@link #original(int)} values.
|
||||
*
|
||||
* @param fieldIndex The 0-based field index in this record.
|
||||
* @see #modified()
|
||||
@ -774,11 +780,13 @@ public interface Record extends Fields, Attachable, Comparable<Record>, Formatta
|
||||
boolean modified(int fieldIndex);
|
||||
|
||||
/**
|
||||
* Check if a field's value has been modified since the record was created or
|
||||
* fetched from the database, using {@link #field(String)} for lookup.
|
||||
* Check if a field's value has been modified since the record was created
|
||||
* or fetched from the database, using {@link #field(String)} for lookup.
|
||||
* <p>
|
||||
* When a record is {@link #modified()}, then it has always been
|
||||
* {@link #touched()} as well.
|
||||
* {@link #touched()} as well. Unlike the {@link #touched(String)} property,
|
||||
* this property cannot be set and is derived only from the comparison
|
||||
* between #get(String) and {@link #original(String)} values.
|
||||
*
|
||||
* @see #modified()
|
||||
* @see #original(String)
|
||||
@ -790,7 +798,9 @@ public interface Record extends Fields, Attachable, Comparable<Record>, Formatta
|
||||
* fetched from the database, using {@link #field(Name)} for lookup.
|
||||
* <p>
|
||||
* When a record is {@link #modified()}, then it has always been
|
||||
* {@link #touched()} as well.
|
||||
* {@link #touched()} as well. Unlike the {@link #touched(Name)} property,
|
||||
* this property cannot be set and is derived only from the comparison
|
||||
* between #get(Name) and {@link #original(Name)} values.
|
||||
*
|
||||
* @see #modified()
|
||||
* @see #original(Name)
|
||||
|
||||
@ -39,6 +39,7 @@ package org.jooq;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.jooq.conf.RecordDirtyTracking;
|
||||
import org.jooq.conf.Settings;
|
||||
import org.jooq.exception.DataAccessException;
|
||||
|
||||
@ -70,7 +71,9 @@ public interface TableRecord<R extends TableRecord<R>> extends QualifiedRecord<R
|
||||
* If you want to enforce re-insertion this record's values, regardless if
|
||||
* the values in this record were touched, you can explicitly set the
|
||||
* touched flags for all values with {@link #touched(boolean)} or for single
|
||||
* values with {@link #touched(Field, boolean)}, prior to insertion.
|
||||
* values with {@link #touched(Field, boolean)}, prior to insertion, if
|
||||
* {@link Settings#getRecordDirtyTracking()} is set to
|
||||
* {@link RecordDirtyTracking#TOUCHED}
|
||||
*
|
||||
* @return <code>1</code> if the record was stored to the database. <code>0
|
||||
* </code> if storing was not necessary and
|
||||
|
||||
@ -37,6 +37,8 @@
|
||||
*/
|
||||
package org.jooq;
|
||||
|
||||
import org.jooq.conf.Settings;
|
||||
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
|
||||
@ -128,9 +130,11 @@ public interface UpdateSetStep<R extends Record> {
|
||||
* Set a value for a field in the <code>UPDATE</code> statement.
|
||||
* <p>
|
||||
* This is the same as calling {@link #set(Map)} with the argument record
|
||||
* treated as a <code>Map<Field<?>, Object></code>, except that the
|
||||
* {@link Record#touched()} flags are taken into consideration in order to
|
||||
* update only touched values.
|
||||
* treated as a <code>Map<Field<?>, Object></code>, except that
|
||||
* the {@link Record#touched()} flags (or {@link Record#modified()} flags,
|
||||
* depending on the query's {@link Settings#getRecordDirtyTracking()}
|
||||
* configuration) are taken into consideration in order to update only
|
||||
* touched (or modified) values.
|
||||
*
|
||||
* @see #set(Map)
|
||||
*/
|
||||
|
||||
37
jOOQ/src/main/java/org/jooq/conf/RecordDirtyTracking.java
Normal file
37
jOOQ/src/main/java/org/jooq/conf/RecordDirtyTracking.java
Normal file
@ -0,0 +1,37 @@
|
||||
|
||||
package org.jooq.conf;
|
||||
|
||||
import jakarta.xml.bind.annotation.XmlEnum;
|
||||
import jakarta.xml.bind.annotation.XmlType;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Java class for RecordDirtyTracking.
|
||||
*
|
||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
||||
* <pre>
|
||||
* <simpleType name="RecordDirtyTracking">
|
||||
* <restriction base="{http://www.w3.org/2001/XMLSchema}string">
|
||||
* <enumeration value="TOUCHED"/>
|
||||
* <enumeration value="MODIFIED"/>
|
||||
* </restriction>
|
||||
* </simpleType>
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
@XmlType(name = "RecordDirtyTracking")
|
||||
@XmlEnum
|
||||
public enum RecordDirtyTracking {
|
||||
|
||||
TOUCHED,
|
||||
MODIFIED;
|
||||
|
||||
public String value() {
|
||||
return name();
|
||||
}
|
||||
|
||||
public static RecordDirtyTracking fromValue(String v) {
|
||||
return valueOf(v);
|
||||
}
|
||||
|
||||
}
|
||||
@ -378,6 +378,9 @@ public class Settings
|
||||
@XmlElement(defaultValue = "NEVER")
|
||||
@XmlSchemaType(name = "string")
|
||||
protected UpdateUnchangedRecords updateUnchangedRecords = UpdateUnchangedRecords.NEVER;
|
||||
@XmlElement(defaultValue = "TOUCHED")
|
||||
@XmlSchemaType(name = "string")
|
||||
protected RecordDirtyTracking recordDirtyTracking = RecordDirtyTracking.TOUCHED;
|
||||
@XmlElement(defaultValue = "false")
|
||||
protected Boolean updatablePrimaryKeys = false;
|
||||
@XmlElement(defaultValue = "true")
|
||||
@ -5175,6 +5178,22 @@ public class Settings
|
||||
this.updateUnchangedRecords = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether {@link org.jooq.UpdatableRecord#store()} and related calls should be based on {@link org.jooq.Record#touched()} or {@link org.jooq.Record#modified()} semantics. This also affects copying records into explicit statements.
|
||||
*
|
||||
*/
|
||||
public RecordDirtyTracking getRecordDirtyTracking() {
|
||||
return recordDirtyTracking;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether {@link org.jooq.UpdatableRecord#store()} and related calls should be based on {@link org.jooq.Record#touched()} or {@link org.jooq.Record#modified()} semantics. This also affects copying records into explicit statements.
|
||||
*
|
||||
*/
|
||||
public void setRecordDirtyTracking(RecordDirtyTracking value) {
|
||||
this.recordDirtyTracking = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether primary key values are deemed to be "updatable" in jOOQ.
|
||||
* <p>
|
||||
@ -8865,6 +8884,15 @@ public class Settings
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether {@link org.jooq.UpdatableRecord#store()} and related calls should be based on {@link org.jooq.Record#touched()} or {@link org.jooq.Record#modified()} semantics. This also affects copying records into explicit statements.
|
||||
*
|
||||
*/
|
||||
public Settings withRecordDirtyTracking(RecordDirtyTracking value) {
|
||||
setRecordDirtyTracking(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether primary key values are deemed to be "updatable" in jOOQ.
|
||||
* <p>
|
||||
@ -9810,6 +9838,7 @@ public class Settings
|
||||
builder.append("attachRecords", attachRecords);
|
||||
builder.append("insertUnchangedRecords", insertUnchangedRecords);
|
||||
builder.append("updateUnchangedRecords", updateUnchangedRecords);
|
||||
builder.append("recordDirtyTracking", recordDirtyTracking);
|
||||
builder.append("updatablePrimaryKeys", updatablePrimaryKeys);
|
||||
builder.append("reflectionCaching", reflectionCaching);
|
||||
builder.append("cacheRecordMappers", cacheRecordMappers);
|
||||
@ -11270,6 +11299,15 @@ public class Settings
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (recordDirtyTracking == null) {
|
||||
if (other.recordDirtyTracking!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!recordDirtyTracking.equals(other.recordDirtyTracking)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (updatablePrimaryKeys == null) {
|
||||
if (other.updatablePrimaryKeys!= null) {
|
||||
return false;
|
||||
@ -12148,6 +12186,7 @@ public class Settings
|
||||
result = ((prime*result)+((attachRecords == null)? 0 :attachRecords.hashCode()));
|
||||
result = ((prime*result)+((insertUnchangedRecords == null)? 0 :insertUnchangedRecords.hashCode()));
|
||||
result = ((prime*result)+((updateUnchangedRecords == null)? 0 :updateUnchangedRecords.hashCode()));
|
||||
result = ((prime*result)+((recordDirtyTracking == null)? 0 :recordDirtyTracking.hashCode()));
|
||||
result = ((prime*result)+((updatablePrimaryKeys == null)? 0 :updatablePrimaryKeys.hashCode()));
|
||||
result = ((prime*result)+((reflectionCaching == null)? 0 :reflectionCaching.hashCode()));
|
||||
result = ((prime*result)+((cacheRecordMappers == null)? 0 :cacheRecordMappers.hashCode()));
|
||||
|
||||
@ -47,6 +47,7 @@ import static org.jooq.conf.SettingsTools.renderLocale;
|
||||
import static org.jooq.impl.DSL.insertInto;
|
||||
import static org.jooq.impl.DSL.name;
|
||||
import static org.jooq.impl.DSL.table;
|
||||
import static org.jooq.impl.Tools.recordDirtyTrackingPredicate;
|
||||
import static org.jooq.tools.StringUtils.abbreviate;
|
||||
import static org.jooq.tools.StringUtils.leftPad;
|
||||
import static org.jooq.tools.StringUtils.rightPad;
|
||||
@ -163,6 +164,7 @@ abstract class AbstractResult<R extends Record> extends AbstractFormattable impl
|
||||
int size = fields.size();
|
||||
final int[] decimalPlaces = new int[size];
|
||||
final int[] widths = new int[size];
|
||||
ObjIntPredicate<Record> dirty = recordDirtyTrackingPredicate(this);
|
||||
|
||||
for (int index = 0; index < size; index++) {
|
||||
if (Number.class.isAssignableFrom(fields.field(index).getType())) {
|
||||
@ -173,7 +175,7 @@ abstract class AbstractResult<R extends Record> extends AbstractFormattable impl
|
||||
|
||||
// Collect all decimal places for the column values
|
||||
for (R record : buffer)
|
||||
decimalPlacesList.add(decimalPlaces(format0(record.get(index), record.touched(index), true)));
|
||||
decimalPlacesList.add(decimalPlaces(format0(record.get(index), dirty.test(record, index), true)));
|
||||
|
||||
// Find max
|
||||
decimalPlaces[index] = Collections.max(decimalPlacesList);
|
||||
@ -197,7 +199,7 @@ abstract class AbstractResult<R extends Record> extends AbstractFormattable impl
|
||||
|
||||
// Add column values width
|
||||
for (R record : buffer) {
|
||||
String value = format0(record.get(index), record.touched(index), true);
|
||||
String value = format0(record.get(index), dirty.test(record, index), true);
|
||||
|
||||
// Align number values before width is calculated
|
||||
if (isNumCol)
|
||||
@ -283,7 +285,7 @@ abstract class AbstractResult<R extends Record> extends AbstractFormattable impl
|
||||
StringUtils.replace(
|
||||
StringUtils.replace(
|
||||
StringUtils.replace(
|
||||
format0(record.get(index), record.touched(index), true), "\n", "{lf}"
|
||||
format0(record.get(index), dirty.test(record, index), true), "\n", "{lf}"
|
||||
), "\r", "{cr}"
|
||||
), "\t", "{tab}"
|
||||
);
|
||||
|
||||
@ -37,6 +37,8 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.impl.Tools.recordDirtyTrackingPredicate;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.jooq.Configuration;
|
||||
@ -72,8 +74,10 @@ implements
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Override
|
||||
public final void setRecord(R record) {
|
||||
ObjIntPredicate<Record> dirty = recordDirtyTrackingPredicate(this);
|
||||
|
||||
for (int i = 0; i < record.size(); i++)
|
||||
if (record.touched(i))
|
||||
if (dirty.test(record, i))
|
||||
addValue((Field) record.field(i), record.get(i));
|
||||
}
|
||||
|
||||
|
||||
@ -1239,7 +1239,7 @@ final class InsertImpl<R extends Record, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10
|
||||
|
||||
@Override
|
||||
public final InsertImpl set(Record record) {
|
||||
return set(Tools.mapOfTouchedValues(record));
|
||||
return set(Tools.mapOfTouchedValues(this, record));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -104,6 +104,7 @@ import static org.jooq.impl.Tools.flattenCollection;
|
||||
import static org.jooq.impl.Tools.map;
|
||||
import static org.jooq.impl.Tools.orElse;
|
||||
import static org.jooq.impl.Tools.qualify;
|
||||
import static org.jooq.impl.Tools.recordDirtyTrackingPredicate;
|
||||
import static org.jooq.impl.Tools.unalias;
|
||||
import static org.jooq.impl.Tools.unqualified;
|
||||
import static org.jooq.impl.Tools.BooleanDataKey.DATA_CONSTRAINT_REFERENCE;
|
||||
@ -306,8 +307,10 @@ implements
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Override
|
||||
public final void setRecordForUpdate(R record) {
|
||||
ObjIntPredicate<Record> dirty = recordDirtyTrackingPredicate(this);
|
||||
|
||||
for (int i = 0; i < record.size(); i++)
|
||||
if (record.touched(i))
|
||||
if (dirty.test(record, i))
|
||||
addValueForUpdate((Field) record.field(i), record.get(i));
|
||||
}
|
||||
|
||||
|
||||
@ -1020,7 +1020,7 @@ implements
|
||||
|
||||
@Override
|
||||
public final MergeImpl set(Record record) {
|
||||
return set(Tools.mapOfTouchedValues(record));
|
||||
return set(Tools.mapOfTouchedValues(this, record));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -65,6 +65,7 @@ import static org.jooq.impl.Tools.filter;
|
||||
import static org.jooq.impl.Tools.indexOrFail;
|
||||
import static org.jooq.impl.Tools.isEmpty;
|
||||
import static org.jooq.impl.Tools.let;
|
||||
import static org.jooq.impl.Tools.recordDirtyTrackingPredicate;
|
||||
import static org.jooq.impl.Tools.settings;
|
||||
import static org.jooq.tools.StringUtils.defaultIfNull;
|
||||
|
||||
@ -308,9 +309,10 @@ implements
|
||||
final List<Field<?>> addTouchedValues(Field<?>[] storeFields, StoreQuery<R> query, boolean forUpdate) {
|
||||
FieldsImpl<Record> f = new FieldsImpl<>(storeFields);
|
||||
List<Field<?>> result = new ArrayList<>();
|
||||
ObjIntPredicate<Record> dirty = recordDirtyTrackingPredicate(query);
|
||||
|
||||
for (Field<?> field : fields.fields.fields) {
|
||||
if (touched(field) && f.field(field) != null && writable(field, forUpdate)) {
|
||||
if (dirty.test(this, indexOf(field)) && f.field(field) != null && writable(field, forUpdate)) {
|
||||
addValue(query, field, forUpdate);
|
||||
result.add(field);
|
||||
}
|
||||
|
||||
@ -268,6 +268,7 @@ import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.function.IntPredicate;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.regex.MatchResult;
|
||||
@ -354,6 +355,7 @@ import org.jooq.conf.BackslashEscaping;
|
||||
import org.jooq.conf.NestedCollectionEmulation;
|
||||
import org.jooq.conf.ParamType;
|
||||
import org.jooq.conf.ParseNameCase;
|
||||
import org.jooq.conf.RecordDirtyTracking;
|
||||
import org.jooq.conf.RenderDefaultNullability;
|
||||
import org.jooq.conf.RenderMapping;
|
||||
import org.jooq.conf.RenderQuotedNames;
|
||||
@ -2790,17 +2792,26 @@ final class Tools {
|
||||
/**
|
||||
* Turn a {@link Record} into a {@link Map}
|
||||
*/
|
||||
static final Map<Field<?>, Object> mapOfTouchedValues(Record record) {
|
||||
static final Map<Field<?>, Object> mapOfTouchedValues(Attachable attachable, Record record) {
|
||||
Map<Field<?>, Object> result = new LinkedHashMap<>();
|
||||
int size = record.size();
|
||||
ObjIntPredicate<Record> dirty = recordDirtyTrackingPredicate(attachable);
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
if (record.touched(i))
|
||||
if (dirty.test(record, i))
|
||||
result.put(record.field(i), record.get(i));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static final ObjIntPredicate<Record> recordDirtyTrackingPredicate(Attachable attachable) {
|
||||
return RecordDirtyTracking.MODIFIED.equals(configuration(attachable).settings().getRecordDirtyTracking())
|
||||
? Record::touched
|
||||
: Record::modified;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Extract the first item from an iterable or <code>null</code>, if there is
|
||||
* no such item, or if iterable itself is <code>null</code>
|
||||
|
||||
@ -60,6 +60,7 @@ import static org.jooq.impl.RecordDelegate.RecordLifecycleType.STORE;
|
||||
import static org.jooq.impl.RecordDelegate.RecordLifecycleType.UPDATE;
|
||||
import static org.jooq.impl.Tools.EMPTY_FIELD;
|
||||
import static org.jooq.impl.Tools.EMPTY_TABLE_FIELD;
|
||||
import static org.jooq.impl.Tools.recordDirtyTrackingPredicate;
|
||||
import static org.jooq.impl.Tools.settings;
|
||||
|
||||
import java.math.BigInteger;
|
||||
@ -204,10 +205,11 @@ public class UpdatableRecordImpl<R extends UpdatableRecord<R>> extends TableReco
|
||||
executeUpdate = fetched;
|
||||
}
|
||||
else {
|
||||
ObjIntPredicate<Record> dirty = recordDirtyTrackingPredicate(this);
|
||||
for (TableField<R, ?> field : keys) {
|
||||
|
||||
// If any primary key value is null or touched
|
||||
if (touched(field) ||
|
||||
if (dirty.test(this, indexOf(field)) ||
|
||||
|
||||
// [#3237] or if a NOT NULL primary key value is null, then execute an INSERT
|
||||
(field.getDataType().nullable() == false && get(field) == null)) {
|
||||
|
||||
@ -178,7 +178,7 @@ implements
|
||||
|
||||
@Override
|
||||
public final UpdateImpl<R> set(Record record) {
|
||||
return set(Tools.mapOfTouchedValues(record));
|
||||
return set(Tools.mapOfTouchedValues(this, record));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1328,6 +1328,10 @@ This flag has no effect when "executeWithOptimisticLocking" is turned off.]]></j
|
||||
<element name="updateUnchangedRecords" type="jooq-runtime:UpdateUnchangedRecords" minOccurs="0" maxOccurs="1" default="NEVER">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Whether {@link org.jooq.UpdatableRecord#update()} calls should be executed if the record is unchanged. This also affects the <code>UPDATE</code> part of {@link org.jooq.UpdatableRecord#store()} and {@link org.jooq.UpdatableRecord#merge()} calls.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="recordDirtyTracking" type="jooq-runtime:RecordDirtyTracking" minOccurs="0" maxOccurs="1" default="TOUCHED">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Whether {@link org.jooq.UpdatableRecord#store()} and related calls should be based on {@link org.jooq.Record#touched()} or {@link org.jooq.Record#modified()} semantics. This also affects copying records into explicit statements.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="updatablePrimaryKeys" type="boolean" minOccurs="0" maxOccurs="1" default="false">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Whether primary key values are deemed to be "updatable" in jOOQ.
|
||||
@ -2398,6 +2402,17 @@ Either <input/> or <inputExpression/> must be provided]]></jxb:javad
|
||||
</restriction>
|
||||
</simpleType>
|
||||
|
||||
<simpleType name="RecordDirtyTracking">
|
||||
<restriction base="string">
|
||||
|
||||
<!-- Dirty tracking is based on Record.touched() semantics -->
|
||||
<enumeration value="TOUCHED"/>
|
||||
|
||||
<!-- Dirty tracking is based on Record.modified() semantics -->
|
||||
<enumeration value="MODIFIED"/>
|
||||
</restriction>
|
||||
</simpleType>
|
||||
|
||||
<simpleType name="Transformation">
|
||||
<restriction base="string">
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user