Available in versions: Dev (3.19) | Latest (3.18) | 3.17

Kotlin coroutine support

Applies to ✅ Open Source Edition   ✅ Express Edition   ✅ Professional Edition   ✅ Enterprise Edition

In kotlin, coroutines and suspending functions are a popular way to implement asynchronous, flow style logic. Starting from jOOQ 3.17, the jooq-kotlin-coroutines extension module allows for bridging between the reactive streams API and the coroutine APIs. For this, simply add the following dependencies:

<dependency>
  <!-- Use org.jooq                for the Open Source Edition
           org.jooq.pro            for commercial editions with Java 17 support, 
           org.jooq.pro-java-11    for commercial editions with Java 11 support,
           org.jooq.pro-java-8     for commercial editions with Java 8 support,
           org.jooq.trial          for the free trial edition with Java 17 support, 
           org.jooq.trial-java-11  for the free trial edition with Java 11 support, 
           org.jooq.trial-java-8   for the free trial edition with Java 8 support 
               
       Note: Only the Open Source Edition is hosted on Maven Central. 
             Import the others manually from your distribution -->
  <groupId>org.jooq</groupId>
  <artifactId>jooq-kotlin</artifactId>
  <version>3.18.0</version>
</dependency>
<dependency>
  <groupId>org.jooq</groupId>
  <artifactId>jooq-kotlin-coroutines</artifactId>
  <version>3.18.0</version>
</dependency>

And now, you can use jOOQ in a kotlin coroutine style:

suspend fun findActor(id: Long): ActorRecord? {
    return create
        .selectFrom(ACTOR)
        .where(ACTOR.ACTOR_ID.eq(id))
        
        // Turn any reactive streams Publisher<T> into a suspension result using the
        // kotlinx-coroutines-reactive extensions
        .awaitFirstOrNull()
}

And wrap your transactional code in the org.jooq.kotlin.coroutines.transactionCoroutine() extension function:

suspend fun insertActorTransaction(): ActorRecord {
    return ctx.transactionCoroutine(::insertActor)
}

suspend fun insertActor(c: Configuration): ActorRecord = c.dsl()
    .insertInto(ACTOR)
    .columns(ACTOR.ACTOR_ID, ACTOR.FIRST_NAME, ACTOR.LAST_NAME)
    .values(201L, "A", "A")
    .returning()
    .awaitFirst()
While jOOQ implements the reactive streams API on top of JDBC by default (in a blocking way), we recommend you consider switching to R2DBC driver usage, if you want your coroutines to be truly non-blocking.

Feedback

Do you have any feedback about this page? We'd love to hear it!

The jOOQ Logo