- Type Parameters:
- R- The record type
- All Superinterfaces:
- Attachable,- Comparable<Record>,- Fields,- Formattable,- QualifiedRecord<R>,- Record,- Serializable,- SQLData,- TableRecord<R>
- All Known Implementing Classes:
- UpdatableRecordImpl
 Any Record can be updatable, if
 
- it represents a record from a table or view - a TableRecord
- its underlying table or view has a "main unique key", i.e. a primary key or at least one unique key
 The "main unique key" is used by jOOQ to perform the various operations that
 can be performed on an UpdatableRecord:
 
- delete(): Deleting the record
- refresh(): Refreshing the records attributes (or loading it for the first time)
- store(): Storing the record to the database. This executes either an- INSERTor an- UPDATEstatement
- merge(): Merging a record to the database. This executes an- INSERT … ON DUPLICATE KEY UPDATEstatement.
 UpdatableRecords are Attachable, which means that they
 hold an underlying Configuration that they can be detached from. They
 can also be instantiated without any underlying Configuration, in
 case of which they have to be attached first, in order to be refreshed,
 stored, or deleted.
- Author:
- Lukas Eder
- 
Method SummaryModifier and TypeMethodDescription<O extends TableRecord<O>>
 @NotNull Table<O>children(ForeignKey<O, R> key) Get a table expression representing the children of this record, given a foreign key.copy()Duplicate this record (in memory) and reset all fields from the primary key or main unique key, such that a subsequent call tostore()will result in anINSERTstatement.intdelete()Deletes this record from the database, based on the value of the primary key or main unique key.<O extends TableRecord<O>>
 OfetchChild(ForeignKey<O, R> key) Fetch a child record of this record, given a foreign key.<O extends TableRecord<O>>
 @NotNull Result<O>fetchChildren(ForeignKey<O, R> key) Fetch child records of this record, given a foreign key.intinsert()Store this record back to the database using anINSERTstatement.intinsert(Collection<? extends Field<?>> fields) Store parts of this record to the database using anINSERTstatement.intStore parts of this record to the database using anINSERTstatement.@NotNull Recordkey()A Record copy holding values for theTable.getPrimaryKey().intmerge()Store this record back to the database using aMERGEstatement.intmerge(Collection<? extends Field<?>> fields) Store parts of this record to the database using aMERGEstatement.intStore parts of this record to the database using aMERGEstatement.voidrefresh()Refresh this record from the database.voidrefresh(Collection<? extends Field<?>> fields) Refresh parts of this record from the database.voidRefresh parts of this record from the database.intstore()Store this record back to the database.intstore(Collection<? extends Field<?>> fields) Store parts of this record to the database.intStore parts of this record to the database.intupdate()Store this record back to the database using anUPDATEstatement.intupdate(Collection<? extends Field<?>> fields) Store parts of this record to the database using anUPDATEstatement.intStore parts of this record to the database using anUPDATEstatement.Methods inherited from interface org.jooq.Attachableattach, configuration, detachMethods inherited from interface org.jooq.FieldsdataType, dataType, dataType, dataTypes, field, field, field, field, field, field, field, field, field, field, fields, fields, fields, fields, fields, fieldsRow, fieldStream, indexOf, indexOf, indexOf, type, type, type, typesMethods inherited from interface org.jooq.Formattableformat, format, format, format, format, format, format, format, format, formatChart, formatChart, formatChart, formatChart, formatChart, formatChart, formatCSV, formatCSV, formatCSV, formatCSV, formatCSV, formatCSV, formatCSV, formatCSV, formatCSV, formatCSV, formatCSV, formatCSV, formatCSV, formatCSV, formatCSV, formatCSV, formatCSV, formatCSV, formatCSV, formatCSV, formatCSV, formatHTML, formatHTML, formatHTML, formatInsert, formatInsert, formatInsert, formatInsert, formatInsert, formatInsert, formatJSON, formatJSON, formatJSON, formatJSON, formatJSON, formatJSON, formatXML, formatXML, formatXML, formatXML, formatXML, formatXML, intoXML, intoXML, intoXML, intoXMLMethods inherited from interface org.jooq.QualifiedRecordgetQualifier, with, withMethods inherited from interface org.jooq.Recordchanged, changed, changed, changed, changed, changed, changed, changed, changed, changed, compareTo, equals, from, from, from, from, from, fromArray, fromArray, fromArray, fromArray, fromArray, fromMap, fromMap, fromMap, fromMap, fromMap, get, get, get, get, get, get, get, get, get, get, get, get, getValue, getValue, getValue, getValue, getValue, getValue, getValue, getValue, getValue, getValue, getValue, getValue, hashCode, into, into, into, into, into, into, into, into, into, into, into, into, into, into, into, into, into, into, into, into, into, into, into, into, into, into, intoArray, intoList, intoMap, intoResultSet, intoStream, map, original, original, original, original, reset, reset, reset, reset, reset, set, set, setValue, setValue, size, valuesRowMethods inherited from interface java.sql.SQLDatagetSQLTypeName, readSQL, writeSQLMethods inherited from interface org.jooq.TableRecordfetchParent, getTable, original, parent
- 
Method Details- 
keyA Record copy holding values for theTable.getPrimaryKey().The returned record consists exactly of those fields as returned by the table's primary key: Key.getFields().Generated subtypes may covariantly override this method to add more record type information. For instance, they may return Record1,Record2, ...
- 
storeStore this record back to the database.Depending on the state of the primary key's value, an insert()or anupdate()statement is executed.Statement type- If this record was created by client code, an INSERTstatement is executed
- If this record was loaded by jOOQ and the primary key value was
 changed, an INSERTstatement is executed (unlessSettings.isUpdatablePrimaryKeys()is set). jOOQ expects that primary key values will never change due to the principle of normalisation in RDBMS. So if client code changes primary key values, this is interpreted by jOOQ as client code wanting to duplicate this record.
- If this record was loaded by jOOQ, and the primary key value was not
 changed, an UPDATEstatement is executed.
 In either statement type, only those fields are inserted/updated, which had been explicitly set by client code, in order to allow for DEFAULTvalues to be applied by the underlying RDBMS. If no fields were modified, neither anUPDATEnor anINSERTwill be executed.Automatic value generationUse insert()orupdate()to explicitly force either statement type.- IDENTITY columns
 If there is an IDENTITYcolumn defined on the record's underlying table (seeTable.getIdentity()), then the auto-generatedIDENTITYvalue is refreshed automatically onINSERT's. Refreshing is done usingStatement.getGeneratedKeys(), where this is supported by the JDBC driver. See alsoInsertQuery.getReturnedRecord()for more details
- VERSION and TIMESTAMP columns
 jOOQ can auto-generate "version" and "timestamp" values that can be used for optimistic locking. If this is an UpdatableRecordand if this record returns fields for eitherTable.getRecordVersion()orTable.getRecordTimestamp(), then these values are set onto theINSERTorUPDATEstatement being executed. On execution success, the generated values are set to this record. Use the code-generation configuration to specify naming patterns for auto-generated "version" and "timestamp" columns.Should you want to circumvent jOOQ-generated updates to these columns, you can render an INSERTorUPDATEstatement manually using the variousDSLContext.insertInto(Table),DSLContext.update(Table)methods.
 Optimistic lockingIf an UPDATEstatement is executed andSettings.isExecuteWithOptimisticLocking()is set totrue, then this record will first be compared with the latest state in the database. There are two modes of operation for optimistic locking:- With VERSION and/or TIMESTAMP columns configured
 This is the preferred way of using optimistic locking in jOOQ. If this is an UpdatableRecordand if this record returns fields for eitherTable.getRecordVersion()orTable.getRecordTimestamp(), then these values are compared to the corresponding value in the database in theWHEREclause of the executedDELETEstatement.
- Without any specific column configurations
 In order to compare this record with the latest state, the database record will be locked pessimistically using a SELECT … FOR UPDATEstatement. Not all databases support theFOR UPDATEclause natively. Namely, the following databases will show slightly different behaviour:- SQLDialect.SQLSERVER: jOOQ will try to lock the database record using- WITH (ROWLOCK, UPDLOCK)hints.
- SQLDialect.SQLITE: No pessimistic locking is possible. Client code must assure that no race-conditions can occur between jOOQ's checking of database record state and the actual- UPDATE
 See SelectQuery.setForUpdate(boolean)for more details
 Statement examplesPossible statements are - INSERT INTO [table] ([modified fields, including keys]) VALUES ([modified values, including keys])
- UPDATE [table] SET [modified fields = modified values, excluding keys] WHERE [key fields = key values] AND [version/timestamp fields = version/timestamp values]
 Statement execution enforcementIf you want to control statement re-execution, regardless if the values in this record were changed, you can explicitly set the changed flags for all values with Record.changed(boolean)or for single values withRecord.changed(Field, boolean), prior to storing. Consider also setting the flagsSettings.getUpdateUnchangedRecords()and/orSettings.isInsertUnchangedRecords()appropriately to control if the record should be "touched" without any changes (UPDATE) or inserted with default values (INSERT).This is the same as calling record.store(record.fields())- Returns:
- 1if the record was stored to the database.- 0if storing was not necessary.
- Throws:
- DataAccessException- if something went wrong executing the query
- DataChangedException- If optimistic locking is enabled and the record has already been changed/deleted in the database
- See Also:
 
- If this record was created by client code, an 
- 
storeStore parts of this record to the database.- Returns:
- 1if the record was stored to the database.- 0if storing was not necessary.
- Throws:
- DataAccessException- if something went wrong executing the query
- DataChangedException- If optimistic locking is enabled and the record has already been changed/deleted in the database
- See Also:
 
- 
store@Support int store(Collection<? extends Field<?>> fields) throws DataAccessException, DataChangedException Store parts of this record to the database.- Returns:
- 1if the record was stored to the database.- 0if storing was not necessary.
- Throws:
- DataAccessException- if something went wrong executing the query
- DataChangedException- If optimistic locking is enabled and the record has already been changed/deleted in the database
- See Also:
 
- 
insertStore this record back to the database using anINSERTstatement.This is the same as store(), except that anINSERTstatement (or no statement) will always be executed.If you want to enforce re-insertion this record's values, regardless if the values in this record were changed, you can explicitly set the changed flags for all values with Record.changed(boolean)or for single values withRecord.changed(Field, boolean), prior to insertion.This is the same as calling record.insert(record.fields())- Specified by:
- insertin interface- TableRecord<R extends UpdatableRecord<R>>
- Returns:
- 1if the record was stored to the database.- 0if storing was not necessary and- Settings.isInsertUnchangedRecords()is set to false.
- Throws:
- DataAccessException- if something went wrong executing the query
- See Also:
 
- 
insertStore parts of this record to the database using anINSERTstatement.- Specified by:
- insertin interface- TableRecord<R extends UpdatableRecord<R>>
- Returns:
- 1if the record was stored to the database.- 0if storing was not necessary.
- Throws:
- DataAccessException- if something went wrong executing the query
- See Also:
 
- 
insertStore parts of this record to the database using anINSERTstatement.- Specified by:
- insertin interface- TableRecord<R extends UpdatableRecord<R>>
- Returns:
- 1if the record was stored to the database.- 0if storing was not necessary.
- Throws:
- DataAccessException- if something went wrong executing the query
- See Also:
 
- 
updateStore this record back to the database using anUPDATEstatement.This is the same as store(), except that anUPDATEstatement (or no statement) will always be executed.If you want to enforce statement execution, regardless if the values in this record were changed, you can explicitly set the changed flags for all values with Record.changed(boolean)or for single values withRecord.changed(Field, boolean), prior to updating, or alternatively, useSettings.getUpdateUnchangedRecords().This is the same as calling record.update(record.fields())- Returns:
- 1if the record was stored to the database.- 0if storing was not necessary.
- Throws:
- DataAccessException- if something went wrong executing the query
- DataChangedException- If optimistic locking is enabled and the record has already been changed/deleted in the database
- See Also:
 
- 
updateStore parts of this record to the database using anUPDATEstatement.- Returns:
- 1if the record was stored to the database.- 0if storing was not necessary.
- Throws:
- DataAccessException- if something went wrong executing the query
- DataChangedException- If optimistic locking is enabled and the record has already been changed/deleted in the database
- See Also:
 
- 
update@Support int update(Collection<? extends Field<?>> fields) throws DataAccessException, DataChangedException Store parts of this record to the database using anUPDATEstatement.- Returns:
- 1if the record was stored to the database.- 0if storing was not necessary.
- Throws:
- DataAccessException- if something went wrong executing the query
- DataChangedException- If optimistic locking is enabled and the record has already been changed/deleted in the database
- See Also:
 
- 
merge@Support({AURORA_MYSQL,AURORA_POSTGRES,COCKROACHDB,CUBRID,DB2,DERBY,FIREBIRD_3_0,H2,HANA,HSQLDB,INFORMIX,MARIADB,MEMSQL,MYSQL,ORACLE,POSTGRES_9_5,SQLITE,SQLSERVER,SYBASE,TERADATA,YUGABYTEDB}) int merge() throws DataAccessExceptionStore this record back to the database using aMERGEstatement.Unlike store(), the statement produced by this operation does not depend on whether the record has been previously fetched from the database or created afresh. It implements the semantics of anINSERT … ON DUPLICATE KEY UPDATEstatement, which will update the row regardless of which (unique) key value is already present. SeeInsertOnDuplicateStep.onDuplicateKeyUpdate().When optimistic locking is active for this record, then this operation will execute insert()orupdate()explicitly, depending on whether the lock values are present already in the record.If you want to enforce statement execution, regardless if the values in this record were changed, you can explicitly set the changed flags for all values with Record.changed(boolean)or for single values withRecord.changed(Field, boolean), prior to insertion.This is the same as calling record.merge(record.fields())- Returns:
- 1if the record was merged to the database.- 0if merging was not necessary.
- Throws:
- DataAccessException- if something went wrong executing the query
- See Also:
 
- 
merge@Support({AURORA_MYSQL,AURORA_POSTGRES,COCKROACHDB,CUBRID,DB2,DERBY,FIREBIRD_3_0,H2,HANA,HSQLDB,INFORMIX,MARIADB,MEMSQL,MYSQL,ORACLE,POSTGRES_9_5,SQLITE,SQLSERVER,SYBASE,TERADATA,YUGABYTEDB}) int merge(Field<?>... fields) throws DataAccessException Store parts of this record to the database using aMERGEstatement.- Returns:
- 1if the record was merged to the database.- 0if merging was not necessary.
- Throws:
- DataAccessException- if something went wrong executing the query
- See Also:
 
- 
merge@Support({AURORA_MYSQL,AURORA_POSTGRES,COCKROACHDB,CUBRID,DB2,DERBY,FIREBIRD_3_0,H2,HANA,HSQLDB,INFORMIX,MARIADB,MEMSQL,MYSQL,ORACLE,POSTGRES_9_5,SQLITE,SQLSERVER,SYBASE,TERADATA,YUGABYTEDB}) int merge(Collection<? extends Field<?>> fields) throws DataAccessException Store parts of this record to the database using aMERGEstatement.- Returns:
- 1if the record was merged to the database.- 0if merging was not necessary.
- Throws:
- DataAccessException- if something went wrong executing the query
- See Also:
 
- 
deleteDeletes this record from the database, based on the value of the primary key or main unique key.Optimistic lockingIf a DELETEstatement is executed andSettings.isExecuteWithOptimisticLocking()is set totrue, then this record will first be compared with the latest state in the database. There are two modes of operation for optimistic locking:- With VERSION and/or TIMESTAMP columns configured
 This is the preferred way of using optimistic locking in jOOQ. If this is an UpdatableRecordand if this record returns fields for eitherTable.getRecordVersion()orTable.getRecordTimestamp(), then these values are compared to the corresponding value in the database in theWHEREclause of the executedDELETEstatement.
- Without any specific column configurations
 In order to compare this record with the latest state, the database record will be locked pessimistically using a SELECT … FOR UPDATEstatement. Not all databases support theFOR UPDATEclause natively. Namely, the following databases will show slightly different behaviour:- SQLDialect.SQLSERVER: jOOQ will try to lock the database record using- WITH (ROWLOCK, UPDLOCK)hints.
- SQLDialect.SQLITE: No pessimistic locking is possible. Client code must assure that no race-conditions can occur between jOOQ's checking of database record state and the actual- DELETE
 See SelectQuery.setForUpdate(boolean)for more details
 Statement examplesThe executed statement is DELETE FROM [table] WHERE [key fields = key values] AND [version/timestamp fields = version/timestamp values]This is in fact the same as calling delete(getTable().getPrimaryKey().getFieldsArray())- Returns:
- 1if the record was deleted from the database.- 0if deletion was not necessary.
- Throws:
- DataAccessException- if something went wrong executing the query
- DataChangedException- If optimistic locking is enabled and the record has already been changed/deleted in the database
 
- With VERSION and/or TIMESTAMP columns configured
 
- 
refreshRefresh this record from the database.A successful refresh results in the following: - Record.valuesRow()will have been restored to the respective values from the database
- TableRecord.original()will match this record
- Record.changed()will be- false
 Refreshing can trigger any of the following actions: - Executing a new SELECTstatement, if this is anUpdatableRecord.
- Failing, otherwise
 This is the same as calling record.refresh(record.fields())- Throws:
- DataAccessException- This exception is thrown if something went wrong executing the refresh- SELECTstatement
- NoDataFoundException- If the record does not exist anymore in the database
 
- 
refreshRefresh parts of this record from the database.A successful refresh results in the following: - Record.valuesRow()will have been restored to the respective values from the database
- TableRecord.original()will match this record
- Record.changed()will be- false
 Refreshing can trigger any of the following actions: - Executing a new SELECTstatement, if this is anUpdatableRecord.
- Failing, otherwise
 This is the same as calling record.refresh(record.fields())- Throws:
- DataAccessException- This exception is thrown if something went wrong executing the refresh- SELECTstatement
- NoDataFoundException- If the record does not exist anymore in the database
 
- 
refresh@Support void refresh(Collection<? extends Field<?>> fields) throws DataAccessException, NoDataFoundException Refresh parts of this record from the database.A successful refresh results in the following: - Record.valuesRow()will have been restored to the respective values from the database
- TableRecord.original()will match this record
- Record.changed()will be- false
 Refreshing can trigger any of the following actions: - Executing a new SELECTstatement, if this is anUpdatableRecord.
- Failing, otherwise
 This is the same as calling record.refresh(record.fields())- Throws:
- DataAccessException- This exception is thrown if something went wrong executing the refresh- SELECTstatement
- NoDataFoundException- If the record does not exist anymore in the database
 
- 
copyDuplicate this record (in memory) and reset all fields from the primary key or main unique key, such that a subsequent call tostore()will result in anINSERTstatement.- Returns:
- A new record, distinct from thisrecord.
 
- 
fetchChild@Nullable @Support @Blocking <O extends TableRecord<O>> O fetchChild(ForeignKey<O, R> key) throws TooManyRowsException, DataAccessExceptionFetch a child record of this record, given a foreign key.This returns a child record referencing this record through a given foreign key, as if fetching from children(ForeignKey).. If no child record was found, this returnsnull.A separate roundtrip is created by this operation. It is often much better to include parent records using ordinary JOINmechanisms in a single query, or using nested records, or theMULTISETorMULTISET_AGGoperators, see https://www.jooq.org/doc/latest/manual/sql-building/column-expressions/nested-records/, or the https://www.jooq.org/doc/latest/manual/sql-building/column-expressions/multiset-value-constructor/.- Throws:
- DataAccessException- if something went wrong executing the query
- TooManyRowsException- if the query returned more than one record
- See Also:
 
- 
fetchChildren@NotNull @Support @Blocking <O extends TableRecord<O>> @NotNull Result<O> fetchChildren(ForeignKey<O, R> key) throws DataAccessExceptionFetch child records of this record, given a foreign key.This returns child records referencing this record through a given foreign key, as if fetching from children(ForeignKey).A separate roundtrip is created by this operation. It is often much better to include parent records using ordinary JOINmechanisms in a single query, or using nested records, or theMULTISETorMULTISET_AGGoperators, see https://www.jooq.org/doc/latest/manual/sql-building/column-expressions/nested-records/, or the https://www.jooq.org/doc/latest/manual/sql-building/column-expressions/multiset-value-constructor/.- Throws:
- DataAccessException- if something went wrong executing the query
- See Also:
 
- 
childrenGet a table expression representing the children of this record, given a foreign key.
 
-