https://kotlinlang.org logo
#exposed
Title
# exposed
w

Wyatt Kennedy

10/04/2023, 3:20 AM
Hi I've got a situation where this github issue is relevant https://github.com/JetBrains/Exposed/issues/1569. Is Andrey's response still accurate, that there is no way to eager fetch one to one and many to one entities without redundant fetches? Are there plans to support this in the future? I have a setup where pretty much every fetch will have a few many to one joins that will cause n + 1 problems if I use entities.
My specific situation in case it's relevant, I have an entity named
UserEntity
and an entity named
UserDataEntity
where
UserDataEntity
is many to one on
UserEntity
. When I fetch
(UserTable innerJoin UserDataTable)
and then use
UserEntity.wrapRows(query)
, the fetch selects all the fields of
UserTable
and
UserDataTable
. However, if I try to use
result.data.<property>
where data is the
referencedOn
property targeting
UserDataEntity
, it refetches the same info from
UserDataTable
.
Something smells fishy here. In my subsequent question, I tried a workaround of doing toList on the query to run the query first, and then calling wrapRow for each entity in the row. What I learned is that just calling wrapRow for my target entity, caused the later call to result.data.<property> to be retrieved from cache. The example in my code base looks like this:
Copy code
private fun fetch(init : SqlExpressionBuilder.() -> Op<Boolean>) : UserDto? {
    val result = (UserTable innerJoin UserDataTable)
       .select(SqlExpressionBuilder.init())
       .toList()
       .firstOrNull()
       ?: return null

    val ent = UserEntity.wrapRow(result)
    UserDataEntity.wrapRow(result) // with this, the print statement below does not cause another fetch.
    println(ent.data.salt)
    return ent.toDto()
}
since it looks like the warm cache is already setup to prevent fetching the same entity multiple times if it's been loaded like from wrapRow, maybe you can add some method to the query to eagerly join fetch a oneToOne or oneToMany?