-
-
Notifications
You must be signed in to change notification settings - Fork 337
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
Registering KotlinMapper with a prefix does not seems to be returning correct results #1944
Comments
Hi @mahesh-chotrani! Thank you for filing an issue. I tried the following test code: package org.jdbi.v3.kotlin
import org.jdbi.v3.core.HandleCallback
import org.jdbi.v3.core.Jdbi
import org.jdbi.v3.core.kotlin.KotlinMapper
import org.jdbi.v3.core.kotlin.mapTo
import org.jdbi.v3.core.mapper.JoinRow
import org.jdbi.v3.core.mapper.JoinRowMapper
import org.jdbi.v3.sqlobject.SqlObjectPlugin
import org.jdbi.v3.sqlobject.kotlin.KotlinSqlObjectPlugin
import org.jdbi.v3.testing.junit5.JdbiExtension
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertNotNull
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.RegisterExtension
class Issue1944Test {
@JvmField
@RegisterExtension
var h2Extension = JdbiExtension.h2()
.withPlugins(SqlObjectPlugin(), KotlinSqlObjectPlugin())
.withInitializer { _, handle ->
handle.inTransaction(HandleCallback<Any?, RuntimeException> { h ->
h.execute("CREATE TABLE Tag (id integer primary key, name VARCHAR(50))")
h.execute("CREATE TABLE Product (id integer primary key, primaryName varchar(50), tagId integer)")
h.execute("INSERT INTO Tag (id, name) VALUES (1, 'foo')")
h.execute("INSERT INTO Product (id, primaryName, tagId) VALUES (2, 'stuff', 1)")
})
}
data class Tag(
val id: Int?,
val name: String?
)
data class Product(
val id: Int?,
val primaryName: String?,
val tagId: Int?,
)
@Test
fun test1944Issue(jdbi: Jdbi) {
val sql = """
SELECT
t.id, t.name,
p.id pid, p.tagId ptagId, p.primaryName pprimaryName
FROM Tag t JOIN Product P ON t.id = p.TagId
""".trimIndent()
val rows = jdbi.withHandle(HandleCallback<List<JoinRow>, RuntimeException> { handle ->
handle.registerRowMapper(Tag::class.java, KotlinMapper(Tag::class.java))
handle.registerRowMapper(Product::class.java, KotlinMapper(Product::class.java, "p"))
handle.registerRowMapper(JoinRowMapper.forTypes(Tag::class.java, Product::class.java))
handle.createQuery(sql).mapTo<JoinRow>().list()
})
assertNotNull(rows)
assertEquals(1, rows.size)
val joinRow = rows[0]
assertEquals(1, joinRow[Tag::class.java].id)
assertEquals("foo", joinRow[Tag::class.java].name)
assertEquals(2, joinRow[Product::class.java].id)
assertEquals("stuff", joinRow[Product::class.java].primaryName)
assertEquals(1, joinRow[Product::class.java].tagId)
}
} and this test passes for me, implying that all the fields (product.id and tag.id) are filled in correctly (this is using jdbi 3.23.0). Do you have a concrete unit test that demonstrates this failure for you? (As a side note: I was not able to use the |
I managed to reproduce the problem with loading the KotlinPlugin and removing the explicit types. |
Thanks for swift response and the unit test, @hgschmie ! Using your sample, I changed my code to use Not sure, if this is an issue with |
Register a custom interceptor with the inference interception framework for the Row mappers. This ensures that KotlinMappers are correctly handled and data objects that have been registered with a prefix are handled correctly. This change fixes jdbi#1944.
This turned out to be a really interesting problem. See #1945 for the full fix. Your previous code should now work unchanged. Fun fact: You did not have to do Fix will be in the next release. Until then, you can use the workaround as decribed above (register with explicit types). |
Thanks @hgschmie for the fix. And the detailed explanation of the issue. I'll use the workaround for now. |
Register a custom interceptor with the inference interception framework for the Row mappers. This ensures that KotlinMappers are correctly handled and data objects that have been registered with a prefix are handled correctly. This change fixes jdbi#1944.
While using
KotlinMapper
, when data is being fetched from more than one tables, and few column names are same from both the tables (like,id
), the result is not populated correctly in the data classes.Here is how a sample query looks like (
id
column is same in both the tables)Tag and Product data classes
And the code snippet
Tag
instance has properid
populated where as theid
inProduct
instances is that ofTag
instances.NOTE If
FieldMapper
is used in place ofKotlinMapper
(and including no-arg constructors in both the data classes), the above code works properly and correct ids are populated inProduct
instances.The text was updated successfully, but these errors were encountered: