in exposed-dao/src/main/kotlin/org/jetbrains/exposed/v1/dao/EntityClass.kt [849:914]
fun <SID> warmUpReferences(
references: List<SID>,
refColumn: Column<SID>,
forUpdate: Boolean? = null,
orderBy: Array<Pair<Expression<*>, SortOrder>>? = null
): List<T> {
val parentTable = refColumn.referee?.table as? IdTable<*>
requireNotNull(parentTable) { "RefColumn should have reference to IdTable" }
if (references.isEmpty()) return emptyList()
val distinctRefIds = references.distinct()
val transaction = TransactionManager.current()
val cache = transaction.entityCache
val keepLoadedReferenceOutOfTransaction = transaction.db.config.keepLoadedReferencesOutOfTransaction
if (refColumn.columnType is EntityIDColumnType<*>) {
refColumn as Column<EntityID<*>>
distinctRefIds as List<EntityID<ID>>
val toLoad: List<EntityID<ID>> = distinctRefIds.filter {
cache.referrers[refColumn]?.containsKey(it)?.not() ?: true
}
if (toLoad.isNotEmpty()) {
val findQuery = find { refColumn inList toLoad }
.orderBy(order = orderBy ?: emptyArray())
val entities = getEntities(forUpdate, findQuery)
val result = entities.groupByReference(refColumn = refColumn)
distinctRefIds.forEach { id ->
cache.getOrPutReferrers(id, refColumn) { result[id]?.let { SizedCollection(it) } ?: emptySized() }.also {
if (keepLoadedReferenceOutOfTransaction) {
cache.find(this, id)?.storeReferenceInCache(refColumn, it)
}
}
}
}
return distinctRefIds.flatMap { cache.getReferrers<T>(it, refColumn)?.toList().orEmpty() }
} else {
val baseQuery = searchQuery(refColumn inList distinctRefIds)
val finalQuery = if (parentTable.id in baseQuery.set.fields) {
baseQuery
} else {
baseQuery.adjustSelect { select(fields + parentTable.id) }
.adjustColumnSet { innerJoin(parentTable, { refColumn }, { refColumn.referee!! }) }
}
.orderBy(order = orderBy ?: emptyArray())
val findQuery = wrapRows(finalQuery)
val entities = getEntities(forUpdate, findQuery).distinct()
entities.groupByReference(refColumn = refColumn).forEach { (id, values) ->
val castReferee = refColumn.referee
.takeUnless { it?.columnType is EntityIDColumnType<*> && id !is EntityID<*> }
?: (refColumn.referee?.columnType as EntityIDColumnType<*>).idColumn
val parentEntityId: EntityID<*> = parentTable.selectAll().where { castReferee as Column<SID> eq id }
.single()[parentTable.id]
cache.getOrPutReferrers(parentEntityId, refColumn) { SizedCollection(values) }.also {
if (keepLoadedReferenceOutOfTransaction) {
val childEntity = find { refColumn eq id }.firstOrNull()
childEntity?.storeReferenceInCache(refColumn, it)
}
}
}
return entities
}
}