升级至Kotlin 2.0.0-RC2后出现类型推断错误求助
Kotlin 2.0.0-RC2升级后Exposed查询类型推断错误问题解析
问题场景
将Kotlin版本升级至2.0.0-RC2后,以下Exposed查询代码中的HostelsTable.id eq HostelFacilitiesJunctionTable.hostel语句出现类型错误:
private fun read(): Query { return HostelsTable.join(Users, JoinType.LEFT, additionalConstraint = { HostelsTable.manager eq Users.uid }) .join(otherTable = HostelFacilitiesJunctionTable, joinType = JoinType.LEFT, additionalConstraint = { HostelsTable.id eq HostelFacilitiesJunctionTable.hostel }) }
相关表定义
object HostelsTable : UUIDTable() { val name = varchar("name", length = 64) }
object HostelFacilitiesJunctionTable : IntIdTable() { val hostel = reference("hostel", HostelsTable, onDelete = ReferenceOption.CASCADE) }
错误信息
Type argument for a type parameter V can't be inferred because it has incompatible upper bounds: UUID, Comparable<UUID>, EntityID<UUID> (multiple incompatible classes: UUID, EntityID<UUID>)
回退至Kotlin 1.9.23版本后,该问题消失。
原因分析
这个问题确实由Kotlin 2.0的类型推断逻辑变更导致:
- Kotlin 2.0大幅提升了泛型类型推断的严谨性,不再像旧版本那样宽松地进行隐式类型适配。
- 代码中
HostelsTable.id的类型为Column<UUID>(继承自UUIDTable),而HostelFacilitiesJunctionTable.hostel的类型是Column<EntityID<UUID>>(reference字段默认返回类型)。 - Kotlin 1.9.23中,Exposed的
eq方法泛型推断可以自动兼容这两种类型,但Kotlin 2.0的严格类型检查直接暴露了这个潜在的类型不匹配。
解决方法
可通过以下两种方式修复问题:
- 显式转换类型:要么将
HostelsTable.id转为EntityID类型,要么提取hostel字段的UUID值进行比较:// 方式一:将id转为EntityID additionalConstraint = { EntityID(HostelsTable.id.value, HostelsTable) eq HostelFacilitiesJunctionTable.hostel } // 方式二:提取hostel的UUID值 additionalConstraint = { HostelsTable.id eq HostelFacilitiesJunctionTable.hostel.value } - 升级Exposed版本:使用适配Kotlin 2.0的Exposed版本(建议0.49.0及以上),这些版本已针对Kotlin 2.0的类型推断逻辑做了适配,可自动处理该类型兼容场景。
内容的提问来源于stack exchange,提问作者ayitinya
相关产品推荐
相关产品推荐

