Skip to content
Advertisement

Set the database current timestamp while inserting using JOOQ

I am using the following code segment to do the insertion using JOOQ’s UpdatableRecord.

public void acknowledgeDisclaimer(AcknowledgeDisclaimerReq acknowledgeDisclaimerReq) {
        DisclaimerRecord disclaimerRecord = dslContext.newRecord(Disclaimer.DISCLAIMER);
        disclaimerRecord.setDisclaimerForId(acknowledgeDisclaimerReq.getDealListingId());
        disclaimerRecord.setDisclaimerForType("DEAL");
        disclaimerRecord.setAcceptedAt(LocalDateTime.now());
        disclaimerRecord.setAcceptedByOwnerId(acknowledgeDisclaimerReq.getLoggedInOwnerId());
        int count = disclaimerRecord.store();
        log.info("Inserted entry for disclaimer for deal: {}, owner: {}, id {}, insertCount: {}", disclaimerRecord.getDisclaimerForId(), disclaimerRecord.getAcceptedByOwnerId(), disclaimerRecord.getId(), count);
}

When setting the AcceptedAt data, I want to use the database’s current timestamp instead of passing the JVM timestamp. Is there any way to do that in JOOQ?

Advertisement

Answer

UpdatableRecord.store() can only set Field<T> => T key/values, not Field<T> => Field<T>, so you cannot set an expression in your record. You can obviously run an explicit INSERT / UPDATE / MERGE statement instead.

Using triggers

The best way to ensure such a timestamp is set to the database timestamp whenever you run some specific DML on the table is to use a database trigger (you could make the trigger watch for changes in the ACCEPTED_BY_OWNER_ID value)

If you can’t do this on the server side (which is the most reliable, because it will behave correctly for all database clients, not just the JDBC/jOOQ based ones), you might have a few client side options in jOOQ:

Using jOOQ 3.17 client side computed columns

jOOQ 3.17 has added support for stored (or virtual) client side computed columns, a special case of which are audit columns (which is almost what you’re doing).

Using this, you can specify, for example:

<forcedType>
  <generator><![CDATA[
    ctx -> org.jooq.impl.DSL.currentTimestamp()
  ]]></generator>
  <includeExpression>(?i:ACCEPTED_AT)</includeExpression>
</forcedType>

The above acts like a trigger that sets the ACCEPTED_AT date to the current timestamp every time you write to the table. In your case, it’ll be more like:

<forcedType>
  <generator><![CDATA[
    ctx -> org.jooq.impl.DSL
      .when(ACCEPTED_BY_OWNER_ID.isNotNull(), org.jooq.impl.DSL.currentTimestamp())
      .else_(ctx.table().ACCEPTED_AT)
  ]]></generator>
  <includeExpression>(?i:ACCEPTED_AT)</includeExpression>
</forcedType>

See a current limitation of the above here:

See the relevant manual sections here:

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement