Skip to content

Commit

Permalink
Many-to-many reference broken in version 0.37.1 JetBrains#1413
Browse files Browse the repository at this point in the history
  • Loading branch information
Tapac committed Dec 29, 2021
1 parent 76a671e commit 8495a76
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ val Transaction.entityCache: EntityCache by transactionScope { EntityCache(this)
class EntityCache(private val transaction: Transaction) {
private var flushingEntities = false
private var initializingEntities: LinkedIdentityHashSet<Entity<*>> = LinkedIdentityHashSet()
internal val pendingInitializationLambdas = IdentityHashMap<Entity<*>, MutableList<(Entity<*>)->Unit>>()
val data = LinkedHashMap<IdTable<*>, MutableMap<Any, Entity<*>>>()
internal val inserts = LinkedHashMap<IdTable<*>, MutableSet<Entity<*>>>()
private val updates = LinkedHashMap<IdTable<*>, MutableSet<Entity<*>>>()
Expand Down Expand Up @@ -86,6 +87,8 @@ class EntityCache(private val transaction: Transaction) {
initializingEntities.remove(entity)
}

internal fun isEntityInInitializationState(entity: Entity<*>) = entity in initializingEntities

fun <ID : Comparable<ID>, T : Entity<ID>> scheduleInsert(f: EntityClass<ID, T>, o: T) {
inserts.getOrPut(f.table) { LinkedIdentityHashSet() }.add(o as Entity<*>)
}
Expand Down Expand Up @@ -199,7 +202,9 @@ class EntityCache(private val transaction: Transaction) {
entry.storeWrittenValues()
store(entry)
transaction.registerChange(entry.klass, entry.id, EntityChangeType.Created)
pendingInitializationLambdas[entry]?.forEach { it(entry) }
}

toFlush = partition.second
} while (toFlush.isNotEmpty())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class InnerTableLink<SID : Comparable<SID>, Source : Entity<SID>, ID : Comparabl
}

override operator fun getValue(o: Source, unused: KProperty<*>): SizedIterable<Target> {
if (o.id._value == null) return emptySized()
if (o.id._value == null && !o.isNewEntity()) return emptySized()
val sourceRefColumn = getSourceRefColumn(o)
val transaction = TransactionManager.currentOrNull()
?: return o.getReferenceFromCache(sourceRefColumn)
Expand All @@ -59,6 +59,17 @@ class InnerTableLink<SID : Comparable<SID>, Source : Entity<SID>, ID : Comparabl
}

override fun setValue(o: Source, unused: KProperty<*>, value: SizedIterable<Target>) {
val entityCache = TransactionManager.current().entityCache
if (entityCache.isEntityInInitializationState(o)) {
entityCache.pendingInitializationLambdas.getOrPut(o) { arrayListOf() }.add {
setReference(it as Source, unused, value)
}
} else {
setReference(o, unused, value)
}
}

private fun setReference(o: Source, unused: KProperty<*>, value: SizedIterable<Target>) {
val sourceRefColumn = getSourceRefColumn(o)

val tx = TransactionManager.current()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,12 @@ class ViaTests : DatabaseTestsBase() {
@Test
fun testHierarchicalReferences() {
withTables(NodeToNodes) {
addLogger(StdOutSqlLogger)
val root = Node.new { name = "root" }
val child1 = Node.new {
name = "child1"
parents = SizedCollection(root)
}
child1.parents = SizedCollection(root)

assertEquals(0L, root.parents.count())
assertEquals(1L, root.children.count())
Expand Down

0 comments on commit 8495a76

Please sign in to comment.