JetBrains / JetBrains/Exposed

Specify condition when eager loading using with()?

Open
#1,492 5 comments 3 reactions 0 assignees View on GitHub
Dominant language
Kotlin
Stars
9.3k
Forks
798
Avg merge
4d 2h
Merged PRs (30d)
26

Description

Is there a way to specify a condition of eager loading when using `with()`? For example, we have a field signifying a soft-deleted row: `deleted`; is there a way to specify that we don't want to eager-fetch rows whose `deleted = 't'`?

```
object XTable : LongIdTable("x") {
val deleted: Column = bool("deleted").default(false)
}

class X(id: EntityID) : LongEntity(id) {
companion object : LongEntityClass(XTable)

var ys by Y via XYTable
var deleted by table.deleted
}

object YTable : LongIdTable("y") {
val deleted: Column = bool("deleted").default(false)
}

class Y(id: EntityID) : LongEntity(id) {
companion object : LongEntityClass(YTable)

var deleted by table.deleted
}

object XYTable : LongIdTable("x_y") {
val xId: Column> = reference(name = "x_id", foreign = XTable)
val yId: Column> = reference(name = "y_id", foreign = YTable)
val deleted: Column = bool("deleted").default(false)
}

class XY(id: EntityID) : LongEntity(id) {
companion object : BaseLongEntityClass(XYTable)

var x by X referencedOn XYTable.xId
var y by Y referencedOn XYTable.yId
val deleted: Column = bool("deleted").default(false)
}
```

Without any conditions, we can eager-load easily as follows:

```
val results = X.all {
if (loadAllYs) {
this.with(X::ys)
}
}
```

But is there a way to specify that we want `XY.deleted = 'f'` and `Y.deleted = 'f'`? I've tried something like the following, but this doesn't eager-load the relationships, i.e. accessing each `X.ys` generates a select query.

```
val results = XTable.innerJoin(XYTable).innerJoin(YTable)
.selectAll().map {
Y.wrapRow(it)
XY.wrapRow(it)
X.wrapRow(it)
}
```

Contributor guide

Open the contributing guide

Research direction

Start by tracing X.all { this.with(X::ys) } and compare it with the XTable.innerJoin(...).selectAll().map { ... } path. Reproduce the soft-delete case using the supplied X, Y, and XY mappings, then determine how conditional eager loading should handle XY.deleted and Y.deleted; done means filtered relations are eagerly loaded without per-X select queries.

Written by the indexing model from the issue text.

Assessment

Tech stack
kotlin, sql
Domain
database
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.