-
Notifications
You must be signed in to change notification settings - Fork 696
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
optReference column should allow update { it[column] = nullableValue } #1275
Comments
Workaround is @Suppress("UNCHECKED_CAST")
operator fun <T, S : Comparable<S>, ID : EntityID<S>?, E : S?> UpdateBuilder<T>.set(column: Column<ID>, value: E) =
// see https://github.com/JetBrains/Exposed/issues/1275
set(column as Column<EntityID<S>>, value) |
A sad case is Table2.update {
it[table1] = null // table1 is optional reference
} both overloads |
Key change is UpdateBuilder#setWithEntityIdValue, which now accepts column: Column<out EntityID<S>?>, value: S? previous signature was column: Column<out EntityID<S>>, value: S? A downside is that "[optionalReferenceColumn] = null" can't decide between "null as ColumnType?" and "null as EntityID<ColumnType>?" update { // it[optionalReferenceColumn] = null // <- does not work // Workaround: specify null type explicitly to call the proper overload it[optionalReferenceColumn] = null as EntityID<ColumnType>? // The following works as well: // it[optionalReferenceColumn] = null as ColumnType? } fixes JetBrains#1275
Key change is UpdateBuilder#setWithEntityIdValue, which now accepts column: Column<out EntityID<S>?>, value: S? previous signature was column: Column<out EntityID<S>>, value: S? A downside is that "[optionalReferenceColumn] = null" can't decide between "null as ColumnType?" and "null as EntityID<ColumnType>?" update { // it[optionalReferenceColumn] = null // <- does not work // Workaround: specify null type explicitly to call the proper overload it[optionalReferenceColumn] = null as EntityID<ColumnType>? // The following works as well: // it[optionalReferenceColumn] = null as ColumnType? } fixes JetBrains#1275
Key change is UpdateBuilder#setWithEntityIdValue, which now accepts column: Column<out EntityID<S>?>, value: S? previous signature was column: Column<out EntityID<S>>, value: S? A downside is that "[optionalReferenceColumn] = null" can't decide between "null as ColumnType?" and "null as EntityID<ColumnType>?" update { // it[optionalReferenceColumn] = null // <- does not work // Workaround: specify null type explicitly to call the proper overload it[optionalReferenceColumn] = null as EntityID<ColumnType>? // The following works as well: // it[optionalReferenceColumn] = null as ColumnType? } fixes JetBrains#1275
Key change is UpdateBuilder#setWithEntityIdValue, which now accepts column: Column<out EntityID<S>?>, value: S? previous signature was column: Column<out EntityID<S>>, value: S? A downside is that "[optionalReferenceColumn] = null" can't decide between "null as ColumnType?" and "null as EntityID<ColumnType>?" update { // it[optionalReferenceColumn] = null // <- does not work // Workaround: specify null type explicitly to call the proper overload it[optionalReferenceColumn] = null as EntityID<ColumnType>? // The following works as well: // it[optionalReferenceColumn] = null as ColumnType? } fixes JetBrains#1275
Key change is UpdateBuilder#setWithEntityIdValue, which now accepts column: Column<out EntityID<S>?>, value: S? previous signature was column: Column<out EntityID<S>>, value: S? A downside is that "[optionalReferenceColumn] = null" can't decide between "null as ColumnType?" and "null as EntityID<ColumnType>?" update { // it[optionalReferenceColumn] = null // <- does not work // Workaround: specify null type explicitly to call the proper overload it[optionalReferenceColumn] = null as EntityID<ColumnType>? // The following works as well: // it[optionalReferenceColumn] = null as ColumnType? } fixes JetBrains#1275
Is there any update on this? or a temporary solution to update optional reference with a simple id value? |
* Libs update: kotlin 1.6.0 kotlin coroutines 1.6.0-RC kotlinx-datetime-jvm 0.3.1 Spring framework 5.3.13 Spring boot 2.6.1 * Add composite foreign key (JetBrains#1385) * optReference column should allow update { it[column] = nullableValue } JetBrains#1275 / Fix test on SQLServer * Performance: cache enumConstants as it makes copy on access * Use h2 version variable in exposed-money (JetBrains#1402) * Better handling for opened result sets + logging * Add H2 version 2.0.202 dialect (JetBrains#1397) * Detekt 1.19.0 * Add H2 version 2.0.202 dialect / Fixes for test configuration * Add H2 version 2.0.202 dialect / Fixes for test configuration #2 * Add H2 version 2.0.202 dialect / Fixes for bitwise operations * Add composite foreign key (JetBrains#1385) / Fix test for SQLServer Co-authored-by: Andrey.Tarashevskiy <[email protected]> Co-authored-by: naftalmm <[email protected]> Co-authored-by: Philip Wedemann <[email protected]>
I tried Exposed 0.37.3, and now it forbids nullable value for nullable foreign key fields. For instance: val optionalInt: Int? = 42
Users.insert {
it[cityId] = optionalInt // should work, however fails with Type mismatch: inferred type is String? but TypeVariable(S) was expected
} |
@Tapac , I'm inclined the issue should be reopened as Exposed still does not allow |
Is there a workaround to achieve that? |
@StefanHUB , my current workarounds (exposed 0.37.3) are fun<ID: Comparable<ID>, T : Entity<ID>> EntityClass<ID, T>.testCache(id: ID) =
testCache(EntityID(id, table))
@Suppress("UNCHECKED_CAST")
operator fun <T, S : Comparable<S>, ID : EntityID<S>?, E : S?> UpdateBuilder<T>.set(column: Column<ID>, value: E) =
// see https://github.com/JetBrains/Exposed/issues/1275
set(column as Column<S?>, value) |
@vlsi Thanks. This works. |
My previous WA included a bug: it allowed to assign nullable value to a non-nullable column. The better WA is as follows: @Suppress("UNCHECKED_CAST")
operator fun <T, S : Comparable<S>, ID : EntityID<S>> UpdateBuilder<T>.set(column: Column<ID?>, value: S?) =
// see https://github.com/JetBrains/Exposed/issues/1275
set(column as Column<S?>, value) The same pattern works for "custom casts". For instance, my database uses So I created the following: @JvmName("setEntityIdLong")
operator fun <T, ID: EntityID<BigDecimal>> UpdateBuilder<T>.set(column: Column<ID>, value: Long) =
set(column, BigDecimal(value))
@Suppress("UNCHECKED_CAST")
@JvmName("setEntityIdLongNullable")
operator fun <T, ID: EntityID<BigDecimal>> UpdateBuilder<T>.set(column: Column<ID?>, value: Long?) =
// see https://github.com/JetBrains/Exposed/issues/1275
set(column as Column<BigDecimal?>, value?.let { BigDecimal(it) }) It enables "automatic" cast to Objects.merge {
it[id] = 9164178420001991212 // id is decimal(...) column (which maps to BigDecimal)
} |
See
Users#cityId
Expected:
Actual: code does not compile.
I suspect the issue is with
UpdateBuilder#setWithEntityIdValue
:Exposed/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/statements/UpdateBuilder.kt
Lines 33 to 38 in d592472
The type of
optReference(...)
isColumn<EntityID<...>?>
which is not compatible withID : EntityID<E>
.It looks like the workaround is to permit
Column<ID?>
.For instance,
Unfortunately, that still allows users to store null to non-nullable columns (however, even the current code allows them to do so).
The text was updated successfully, but these errors were encountered: