diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Column.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Column.kt index ecedf8f0ed..c585a4a141 100644 --- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Column.kt +++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Column.kt @@ -30,7 +30,7 @@ class Column( val referee: Column<*>? get() = foreignKey?.targetOf(this) - /** Returns the column that this column references, casted as a column of type [S], or `null` if the cast fails. */ + /** Returns the column that this column references, cast as a column of type [S], or `null` if the cast fails. */ @Suppress("UNCHECKED_CAST") fun referee(): Column? = referee as? Column diff --git a/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/Entity.kt b/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/Entity.kt index ea2c62286d..a9150e8730 100644 --- a/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/Entity.kt +++ b/exposed-dao/src/main/kotlin/org/jetbrains/exposed/dao/Entity.kt @@ -125,15 +125,15 @@ open class Entity>(val id: EntityID) { } } else -> { - // @formatter:off + val castReferee = reference.referee()!! + val baseReferee = (castReferee.columnType as? EntityIDColumnType)?.idColumn ?: castReferee factory.findWithCacheCondition({ reference.referee!!.getValue(this, desc) == refValue }) { - reference.referee()!! eq refValue + baseReferee eq refValue }.singleOrNull()?.also { storeReferenceInCache(reference, it) } - // @formatter:on } } ?: error("Cannot find ${factory.table.tableName} WHERE id=$refValue") } diff --git a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/entities/LongIdTableEntityTest.kt b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/entities/LongIdTableEntityTest.kt index e2b020177d..532549209d 100644 --- a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/entities/LongIdTableEntityTest.kt +++ b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/entities/LongIdTableEntityTest.kt @@ -4,7 +4,10 @@ import org.jetbrains.exposed.dao.LongEntity import org.jetbrains.exposed.dao.LongEntityClass import org.jetbrains.exposed.dao.id.EntityID import org.jetbrains.exposed.dao.id.LongIdTable +import org.jetbrains.exposed.sql.Column import org.jetbrains.exposed.sql.exists +import org.jetbrains.exposed.sql.insert +import org.jetbrains.exposed.sql.insertAndGetId import org.jetbrains.exposed.sql.tests.DatabaseTestsBase import org.jetbrains.exposed.sql.tests.shared.assertEquals import org.junit.Test @@ -13,30 +16,43 @@ object LongIdTables { object Cities : LongIdTable() { val name = varchar("name", 50) } + class City(id: EntityID) : LongEntity(id) { companion object : LongEntityClass(Cities) var name by Cities.name } + object People : LongIdTable() { val name = varchar("name", 80) val cityId = reference("city_id", Cities) } + class Person(id: EntityID) : LongEntity(id) { companion object : LongEntityClass(People) var name by People.name var city by City referencedOn People.cityId } + + object Towns : LongIdTable("towns") { + val cityId: Column = long("city_id").references(Cities.id) + } + + class Town(id: EntityID) : LongEntity(id) { + companion object : LongEntityClass(Towns) + var city by City referencedOn Towns.cityId + } } class LongIdTableEntityTest : DatabaseTestsBase() { - - @Test fun `create tables`() { + @Test + fun `create tables`() { withTables(LongIdTables.Cities, LongIdTables.People) { assertEquals(true, LongIdTables.Cities.exists()) assertEquals(true, LongIdTables.People.exists()) } } - @Test fun `create records`() { + @Test + fun `create records`() { withTables(LongIdTables.Cities, LongIdTables.People) { val mumbai = LongIdTables.City.new { name = "Mumbai" } val pune = LongIdTables.City.new { name = "Pune" } @@ -64,7 +80,8 @@ class LongIdTableEntityTest : DatabaseTestsBase() { } } - @Test fun `update and delete records`() { + @Test + fun `update and delete records`() { withTables(LongIdTables.Cities, LongIdTables.People) { val mumbai = LongIdTables.City.new { name = "Mumbai" } val pune = LongIdTables.City.new { name = "Pune" } @@ -93,4 +110,19 @@ class LongIdTableEntityTest : DatabaseTestsBase() { assertEquals(false, allPeople.contains(Pair("Tanu Arora", "Pune"))) } } + + @Test + fun testForeignKeyBetweenLongAndEntityIDColumns() { + withTables(LongIdTables.Cities, LongIdTables.Towns) { + val cId = LongIdTables.Cities.insertAndGetId { + it[name] = "City A" + } + LongIdTables.Towns.insert { + it[cityId] = cId.value + } + + val town1 = LongIdTables.Town.all().single() + assertEquals(cId, town1.city.id) + } + } } diff --git a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/entities/UuidTableEntityTest.kt b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/entities/UuidTableEntityTest.kt index 968463d18f..f017a95713 100644 --- a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/entities/UuidTableEntityTest.kt +++ b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/entities/UuidTableEntityTest.kt @@ -4,7 +4,10 @@ import org.jetbrains.exposed.dao.UUIDEntity import org.jetbrains.exposed.dao.UUIDEntityClass import org.jetbrains.exposed.dao.id.EntityID import org.jetbrains.exposed.dao.id.UUIDTable +import org.jetbrains.exposed.sql.Column import org.jetbrains.exposed.sql.exists +import org.jetbrains.exposed.sql.insert +import org.jetbrains.exposed.sql.insertAndGetId import org.jetbrains.exposed.sql.tests.DatabaseTestsBase import org.jetbrains.exposed.sql.tests.shared.assertEquals import org.junit.Test @@ -47,10 +50,18 @@ object UUIDTables { var city by City.referencedOn(Addresses.city) var address by Addresses.address } + + object Towns : UUIDTable("towns") { + val cityId: Column = uuid("city_id").references(Cities.id) + } + + class Town(id: EntityID) : UUIDEntity(id) { + companion object : UUIDEntityClass(Towns) + var city by City referencedOn Towns.cityId + } } class UUIDTableEntityTest : DatabaseTestsBase() { - @Test fun `create tables`() { withTables(UUIDTables.Cities, UUIDTables.People) { @@ -149,4 +160,19 @@ class UUIDTableEntityTest : DatabaseTestsBase() { assertEquals("address2", address2.address) } } + + @Test + fun testForeignKeyBetweenUUIDAndEntityIDColumns() { + withTables(UUIDTables.Cities, UUIDTables.Towns) { + val cId = UUIDTables.Cities.insertAndGetId { + it[name] = "City A" + } + UUIDTables.Towns.insert { + it[cityId] = cId.value + } + + val town1 = UUIDTables.Town.all().single() + assertEquals(cId, town1.city.id) + } + } }