Kotlin Support

Last updated 3 days ago

ObjectBox and Kotlin

ObjectBox comes with full Kotlin support for Android. This allows entities to be modeled in Kotlin classes (regular and data classes). With Kotlin support you can build faster apps even faster.

This page assumes that you have added ObjectBox to your project and that you are familiar with basic functionality. The Getting Started page will help you out if you are not. This page discusses additional steps and differences for Kotlin only.

Kotlin Entities

In Kotlin, different from the default way to annotate entities, you should define ID properties like this:

@Id var id: Long = 0

The ID must be a var (not a val) because ObjectBox assigns an ID after putting a new entity. Also, IDs should be of primitive type Long with the special value of zero for marking entities as new.

So a simple data class looks like this:

@Entity
data class Note(
@Id var id: Long = 0,
val text: String
)

Entity Constructors

ObjectBox needs to call a constructor to create objects. It will choose one of these two:

  • All-args constructor: If ObjectBox finds a constructor that matches all persisted properties (types and names are checked), it will call it preferably.

  • No-args constructor: fall back if it does not find an all-args constructor. ObjectBox will initialize fields after calling the no-args (default) constructor.

Note that Kotlin data classes usually provide a compatible all-args constructor. However, ObjectBox can not use it if custom or transient properties or relations are part of the constructor parameters. In this case you can provide default values which will ensure a no-args constructor exists:

@Entity
data class Note(
@Id var id: Long = 0,
val text: String = "",
@Convert(converter = StringsConverter::class, dbType = String::class)
val strings: List<String> = listOf()
)

Defining Relations in Kotlin Entities

Defining relations in Kotlin pretty much works as expected.

However, keep in mind that relation properties have to be var, they can not be val. Otherwise the “initialization magic” as described in the relations docs will not work.

You also typically would use a lateinit modifier for relation properties.

An example:

@Entity
class Order {
@Id var id: Long = 0
lateinit var customer: ToOne<Customer>
}
@Entity
class Customer {
@Id var id: Long = 0
@Backlink(to = "customer")
lateinit var orders: List<Order>
}

Using the provided extension functions

Since 2.0.0

After setting up your project, you also might want to add our Kotlin extension functions. We provide a tiny additional library that we intend to grow in the future (see below for what works today).

Just add it to the existing dependencies in your app's build.gradle file:

dependencies {
implementation "io.objectbox:objectbox-kotlin:$objectboxVersion"
}

Now have a look at what is possible with the extensions compared to standard Kotlin idioms:

Get a box:

// Regular
val box: Box<DataClassEntity> = store.boxFor(DataClassEntity::class.java)
// With extension
val box: Box<DataClassEntity> = store.boxFor()

Build a query:

// Regular
val query = box.query().run {
equal(property, value)
order(property)
build()
}
// With extension
val query = box.query {
equal(property, value)
order(property)
}

Use the in filter of a query:

// Regular
val query = box.query().`in`(property, array).build()
// With extension
val query = box.query().inValues(property, array).build()

Modify a ToMany:

// Regular
toMany.apply {
reset()
add(entity)
removeById(id)
applyChangesToDb()
}
// With extension
toMany.applyChangesToDb(resetFirst = true) { // default is false
add(entity)
removeById(id)
}

Something missing? Let us know what other extension functions you want us to add.