From 87f1b97a6c3499d8505fde59153f55094a2eefee Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sat, 24 Apr 2021 17:13:47 +0900 Subject: [PATCH 1/8] =?UTF-8?q?ConversionService=E4=BB=98=E3=81=8D?= =?UTF-8?q?=E3=82=B3=E3=83=B3=E3=82=B9=E3=83=88=E3=83=A9=E3=82=AF=E3=82=BF?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/mapk/krowmapper/DummyConstructor.kt | 7 ++++ .../kotlin/com/mapk/krowmapper/KRowMapper.kt | 34 +++++++++++++++---- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/com/mapk/krowmapper/DummyConstructor.kt b/src/main/kotlin/com/mapk/krowmapper/DummyConstructor.kt index a8b8f6e..310b773 100644 --- a/src/main/kotlin/com/mapk/krowmapper/DummyConstructor.kt +++ b/src/main/kotlin/com/mapk/krowmapper/DummyConstructor.kt @@ -1,7 +1,14 @@ package com.mapk.krowmapper +import org.springframework.core.convert.ConversionService import com.mapk.krowmapper.KRowMapper as Mapper +@Suppress("FunctionName") +inline fun KRowMapper( + conversionService: ConversionService, + noinline parameterNameConverter: ((String) -> String)? = null +) = Mapper(T::class, conversionService, parameterNameConverter) + @Suppress("FunctionName") inline fun KRowMapper( noinline parameterNameConverter: ((String) -> String)? = null diff --git a/src/main/kotlin/com/mapk/krowmapper/KRowMapper.kt b/src/main/kotlin/com/mapk/krowmapper/KRowMapper.kt index 8f4832e..6ac3222 100644 --- a/src/main/kotlin/com/mapk/krowmapper/KRowMapper.kt +++ b/src/main/kotlin/com/mapk/krowmapper/KRowMapper.kt @@ -2,20 +2,40 @@ package com.mapk.krowmapper import com.mapk.core.KFunctionForCall import com.mapk.core.toKConstructor +import org.springframework.core.convert.ConversionService +import org.springframework.core.convert.support.DefaultConversionService import org.springframework.jdbc.core.RowMapper import java.sql.ResultSet import kotlin.reflect.KClass import kotlin.reflect.KFunction -class KRowMapper private constructor(private val function: KFunctionForCall) : RowMapper { - constructor(function: KFunction, parameterNameConverter: ((String) -> String)? = null) : this( - KFunctionForCall(function, parameterNameConverter) - ) +class KRowMapper private constructor( + private val function: KFunctionForCall, + conversionService: ConversionService? +) : RowMapper { + constructor( + function: KFunction, + conversionService: ConversionService, + parameterNameConverter: ((String) -> String)? = null + ) : this(KFunctionForCall(function, parameterNameConverter), conversionService) - constructor(clazz: KClass, parameterNameConverter: ((String) -> String)? = null) : this( - clazz.toKConstructor(parameterNameConverter) - ) + constructor( + function: KFunction, + parameterNameConverter: ((String) -> String)? = null + ) : this(KFunctionForCall(function, parameterNameConverter), null) + constructor( + clazz: KClass, + conversionService: ConversionService, + parameterNameConverter: ((String) -> String)? = null + ) : this(clazz.toKConstructor(parameterNameConverter), conversionService) + + constructor( + clazz: KClass, + parameterNameConverter: ((String) -> String)? = null + ) : this(clazz.toKConstructor(parameterNameConverter), null) + + private val conversionService: ConversionService = conversionService ?: DefaultConversionService.getSharedInstance() private val parameters: List> = function.requiredParameters.map { ParameterForMap.newInstance(it) } From c8dfc1fb37f1e0e8717f1a6035e3495a31462c2a Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 25 Apr 2021 16:26:50 +0900 Subject: [PATCH 2/8] =?UTF-8?q?ConversionService=E3=82=92=E7=94=A8?= =?UTF-8?q?=E3=81=84=E3=81=9F=E5=A4=89=E6=8F=9B=E3=82=92=E8=A1=8C=E3=81=86?= =?UTF-8?q?=E5=BD=A2=E3=81=AB=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/mapk/krowmapper/KRowMapper.kt | 2 +- .../com/mapk/krowmapper/ParameterForMap.kt | 30 ++++++++++++++----- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/com/mapk/krowmapper/KRowMapper.kt b/src/main/kotlin/com/mapk/krowmapper/KRowMapper.kt index 6ac3222..5dd51fc 100644 --- a/src/main/kotlin/com/mapk/krowmapper/KRowMapper.kt +++ b/src/main/kotlin/com/mapk/krowmapper/KRowMapper.kt @@ -37,7 +37,7 @@ class KRowMapper private constructor( private val conversionService: ConversionService = conversionService ?: DefaultConversionService.getSharedInstance() private val parameters: List> = - function.requiredParameters.map { ParameterForMap.newInstance(it) } + function.requiredParameters.map { ParameterForMap.newInstance(it, this.conversionService) } override fun mapRow(rs: ResultSet, rowNum: Int): T { val adaptor = function.getArgumentAdaptor() diff --git a/src/main/kotlin/com/mapk/krowmapper/ParameterForMap.kt b/src/main/kotlin/com/mapk/krowmapper/ParameterForMap.kt index 7eba1b7..0312b3b 100644 --- a/src/main/kotlin/com/mapk/krowmapper/ParameterForMap.kt +++ b/src/main/kotlin/com/mapk/krowmapper/ParameterForMap.kt @@ -9,6 +9,7 @@ import com.mapk.core.getAnnotatedFunctionsFromCompanionObject import com.mapk.core.getKClass import com.mapk.deserialization.AbstractKColumnDeserializer import com.mapk.deserialization.KColumnDeserializeBy +import org.springframework.core.convert.ConversionService import java.lang.IllegalArgumentException import java.sql.ResultSet import kotlin.reflect.KClass @@ -23,8 +24,18 @@ internal sealed class ParameterForMap { abstract val name: String abstract fun getObject(rs: ResultSet): D? - private class Plain(override val name: String, val requiredClazz: Class) : ParameterForMap() { - override fun getObject(rs: ResultSet): T? = rs.getObject(name, requiredClazz) + private class Default( + override val name: String, + val requiredClazz: Class, + private val conversionService: ConversionService + ) : ParameterForMap() { + override fun getObject(rs: ResultSet): D? = rs.getObject(name)?.let { + if (requiredClazz.isInstance(it)) + @Suppress("UNCHECKED_CAST") + it as D? + else + conversionService.convert(it, requiredClazz) + } } private class Enum(override val name: String, val enumClazz: Class) : ParameterForMap() { @@ -45,20 +56,25 @@ internal sealed class ParameterForMap { } companion object { - fun newInstance(param: ValueParameter): ParameterForMap<*, T> { + fun newInstance( + param: ValueParameter, + conversionService: ConversionService + ): ParameterForMap<*, T> { param.getDeserializer()?.let { return Deserializer(param.name, it) } param.requiredClazz.getDeserializer()?.let { - val targetClass = it.parameters.single().getKClass().javaObjectType - return Deserializer(param.name, targetClass, it) + val srcClass = it.parameters.single().getKClass().javaObjectType + return Deserializer(param.name, srcClass, it) } - return param.requiredClazz.javaObjectType.let { + val requiredClazz = param.requiredClazz.javaObjectType + + return requiredClazz.let { when (it.isEnum) { true -> Enum(param.name, it) - false -> Plain(param.name, it) + false -> Default(param.name, it, conversionService) } } } From bdd7750bf833c212c7e4b57c5742e2bd801073c1 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 25 Apr 2021 16:30:41 +0900 Subject: [PATCH 3/8] =?UTF-8?q?=E3=83=86=E3=82=B9=E3=83=88=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/mapk/krowmapper/DefaultValueTest.kt | 4 ++-- .../com/mapk/krowmapper/KParameterFlattenTest.kt | 12 ++++++------ .../kotlin/com/mapk/krowmapper/SimpleMappingTest.kt | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/test/kotlin/com/mapk/krowmapper/DefaultValueTest.kt b/src/test/kotlin/com/mapk/krowmapper/DefaultValueTest.kt index f96f108..fe77d11 100644 --- a/src/test/kotlin/com/mapk/krowmapper/DefaultValueTest.kt +++ b/src/test/kotlin/com/mapk/krowmapper/DefaultValueTest.kt @@ -19,7 +19,7 @@ class DefaultValueTest { @DisplayName("デフォルト値を用いたマッピングテスト") fun test() { val resultSet = mockk() - every { resultSet.getObject("foo_id", any>()) } returns 1 + every { resultSet.getObject("foo_id") } returns 1 every { resultSet.getObject("bar_value", any>()) } returns "From result set." val result = KRowMapper(Dst::class, this::camelToSnake).mapRow(resultSet, 0) @@ -27,7 +27,7 @@ class DefaultValueTest { Assertions.assertEquals(1, result.fooId) Assertions.assertEquals("default", result.barValue) - verify(exactly = 1) { resultSet.getObject("foo_id", Integer::class.java) } + verify(exactly = 1) { resultSet.getObject("foo_id") } verify(exactly = 0) { resultSet.getObject("bar_value", String::class.java) } } } diff --git a/src/test/kotlin/com/mapk/krowmapper/KParameterFlattenTest.kt b/src/test/kotlin/com/mapk/krowmapper/KParameterFlattenTest.kt index fa5b8f9..9e65dce 100644 --- a/src/test/kotlin/com/mapk/krowmapper/KParameterFlattenTest.kt +++ b/src/test/kotlin/com/mapk/krowmapper/KParameterFlattenTest.kt @@ -28,16 +28,16 @@ class KParameterFlattenTest { @DisplayName("スネークケースsrc -> キャメルケースdst") fun test() { val resultSet = mockk() { - every { getObject("baz_baz_foo_foo", any>()) } returns 1 - every { getObject("baz_baz_bar_bar", any>()) } returns "str" - every { getObject("qux_qux", any>()) } returns LocalDateTime.MIN + every { getObject("baz_baz_foo_foo") } returns 1 + every { getObject("baz_baz_bar_bar") } returns "str" + every { getObject("qux_qux") } returns LocalDateTime.MIN } val result = KRowMapper(this::camelToSnake).mapRow(resultSet, 0) assertEquals(expected, result) - verify(exactly = 1) { resultSet.getObject("baz_baz_foo_foo", Integer::class.java) } - verify(exactly = 1) { resultSet.getObject("baz_baz_bar_bar", String::class.java) } - verify(exactly = 1) { resultSet.getObject("qux_qux", LocalDateTime::class.java) } + verify(exactly = 1) { resultSet.getObject("baz_baz_foo_foo") } + verify(exactly = 1) { resultSet.getObject("baz_baz_bar_bar") } + verify(exactly = 1) { resultSet.getObject("qux_qux") } } } diff --git a/src/test/kotlin/com/mapk/krowmapper/SimpleMappingTest.kt b/src/test/kotlin/com/mapk/krowmapper/SimpleMappingTest.kt index f2b07bb..3c93a9e 100644 --- a/src/test/kotlin/com/mapk/krowmapper/SimpleMappingTest.kt +++ b/src/test/kotlin/com/mapk/krowmapper/SimpleMappingTest.kt @@ -19,15 +19,15 @@ class SimpleMappingTest { @DisplayName("スネークケースsrc -> キャメルケースdst") fun test() { val resultSet = mockk() - every { resultSet.getObject("foo_id", any>()) } returns 1 - every { resultSet.getObject("str_value", any>()) } returns "str" + every { resultSet.getObject("foo_id") } returns 1 + every { resultSet.getObject("str_value") } returns "str" val result = KRowMapper(::Dst, this::camelToSnake).mapRow(resultSet, 0) assertEquals(1, result.fooId) assertEquals("str", result.strValue) - verify(exactly = 1) { resultSet.getObject("foo_id", Integer::class.java) } - verify(exactly = 1) { resultSet.getObject("str_value", String::class.java) } + verify(exactly = 1) { resultSet.getObject("foo_id") } + verify(exactly = 1) { resultSet.getObject("str_value") } } } From a2c568fedb0c1272a422e3f24e53333ee0aee656 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 25 Apr 2021 17:15:13 +0900 Subject: [PATCH 4/8] =?UTF-8?q?=E3=82=A8=E3=83=A9=E3=83=BC=E3=83=A1?= =?UTF-8?q?=E3=83=83=E3=82=BB=E3=83=BC=E3=82=B8=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/mapk/krowmapper/ParameterForMap.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/com/mapk/krowmapper/ParameterForMap.kt b/src/main/kotlin/com/mapk/krowmapper/ParameterForMap.kt index 0312b3b..884d236 100644 --- a/src/main/kotlin/com/mapk/krowmapper/ParameterForMap.kt +++ b/src/main/kotlin/com/mapk/krowmapper/ParameterForMap.kt @@ -9,6 +9,7 @@ import com.mapk.core.getAnnotatedFunctionsFromCompanionObject import com.mapk.core.getKClass import com.mapk.deserialization.AbstractKColumnDeserializer import com.mapk.deserialization.KColumnDeserializeBy +import org.springframework.core.convert.ConversionException import org.springframework.core.convert.ConversionService import java.lang.IllegalArgumentException import java.sql.ResultSet @@ -33,8 +34,11 @@ internal sealed class ParameterForMap { if (requiredClazz.isInstance(it)) @Suppress("UNCHECKED_CAST") it as D? - else + else try { conversionService.convert(it, requiredClazz) + } catch (ex: ConversionException) { + throw IllegalStateException("Could not find a method to deserialize for '$name' parameter.", ex) + } } } From e515305a3a3664fb0438fa8d805d57ef31e1c6a9 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 25 Apr 2021 18:00:53 +0900 Subject: [PATCH 5/8] =?UTF-8?q?=E3=83=86=E3=82=B9=E3=83=88=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DeserializeByConversionServiceTest.kt | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/test/kotlin/com/mapk/krowmapper/DeserializeByConversionServiceTest.kt diff --git a/src/test/kotlin/com/mapk/krowmapper/DeserializeByConversionServiceTest.kt b/src/test/kotlin/com/mapk/krowmapper/DeserializeByConversionServiceTest.kt new file mode 100644 index 0000000..9b943d4 --- /dev/null +++ b/src/test/kotlin/com/mapk/krowmapper/DeserializeByConversionServiceTest.kt @@ -0,0 +1,30 @@ +package com.mapk.krowmapper + +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Test +import org.springframework.core.convert.ConversionService +import java.sql.ResultSet +import java.time.YearMonth + +@DisplayName("ConversionServiceによるデシリアライズのテスト") +private class DeserializeByConversionServiceTest { + data class Dst(val yearMonth: YearMonth) + + @Test + fun test() { + val conversionService = mockk { + every { convert(202101, YearMonth::class.java) } returns (YearMonth.of(2021, 1)) + } + val mapper = KRowMapper(conversionService) + val resultSet = mockk { + every { getObject("yearMonth") } returns 202101 + } + + assertEquals(Dst(YearMonth.of(2021, 1)), mapper.mapRow(resultSet, 0)) + verify(exactly = 1) { conversionService.convert(202101, YearMonth::class.java) } + } +} From 57a486f88e0c2c349c1167bac005812c4acc2544 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 25 Apr 2021 18:05:26 +0900 Subject: [PATCH 6/8] =?UTF-8?q?String=20->=20Enum=E3=81=AE=E5=A4=89?= =?UTF-8?q?=E6=8F=9B=E3=81=AFSpring=E3=81=AE=E3=82=B3=E3=83=B3=E3=83=90?= =?UTF-8?q?=E3=83=BC=E3=82=BF=E3=83=BC=E3=81=8C=E6=8F=90=E4=BE=9B=E3=81=95?= =?UTF-8?q?=E3=82=8C=E3=81=A6=E3=81=84=E3=82=8B=E3=81=9F=E3=82=81=E5=89=8A?= =?UTF-8?q?=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/mapk/krowmapper/ParameterForMap.kt | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/main/kotlin/com/mapk/krowmapper/ParameterForMap.kt b/src/main/kotlin/com/mapk/krowmapper/ParameterForMap.kt index 884d236..e59b0ae 100644 --- a/src/main/kotlin/com/mapk/krowmapper/ParameterForMap.kt +++ b/src/main/kotlin/com/mapk/krowmapper/ParameterForMap.kt @@ -1,7 +1,6 @@ package com.mapk.krowmapper import com.mapk.annotations.KColumnDeserializer -import com.mapk.core.EnumMapper import com.mapk.core.KFunctionWithInstance import com.mapk.core.ValueParameter import com.mapk.core.getAnnotatedFunctions @@ -42,10 +41,6 @@ internal sealed class ParameterForMap { } } - private class Enum(override val name: String, val enumClazz: Class) : ParameterForMap() { - override fun getObject(rs: ResultSet): D? = EnumMapper.getEnum(enumClazz, rs.getString(name)) - } - private class Deserializer( override val name: String, val srcClazz: Class, @@ -73,14 +68,7 @@ internal sealed class ParameterForMap { return Deserializer(param.name, srcClass, it) } - val requiredClazz = param.requiredClazz.javaObjectType - - return requiredClazz.let { - when (it.isEnum) { - true -> Enum(param.name, it) - false -> Default(param.name, it, conversionService) - } - } + return Default(param.name, param.requiredClazz.javaObjectType, conversionService) } } } From 4b230ce63a074e252a3347c105e1d3030aa57bff Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 25 Apr 2021 18:20:30 +0900 Subject: [PATCH 7/8] =?UTF-8?q?README=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.ja.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/README.ja.md b/README.ja.md index c267d9f..a7546f2 100644 --- a/README.ja.md +++ b/README.ja.md @@ -98,6 +98,9 @@ val dst: Dst = jdbcTemplate.query(query, KRowMapper(::Dst, /* 必要に応じた また、`KRowMapper`はデフォルトでは引数名によってカラムとの対応を見るため、「引数がキャメルケースでカラムはスネークケース」というような場合、引数名を変換する関数も渡す必要が有ります。 +必要に応じて値の変換のために`ConversionService`を渡すこともできます。 +渡さなかった場合、`DefaultConversionService.sharedInstance`がデフォルトとして利用されます。 + ### method reference(KFunction)からの初期化 `KRowMapper`は`method reference`から初期化できます。 @@ -230,13 +233,16 @@ val mapper: KRowMapper = KRowMapper(::Dst, parameterNameConverter) ただし、よりプレーンな`Kotlin`に近い書き方をしたい場合にはこれらの機能を用いず、呼び出し対象メソッドで全ての初期化処理を書くことをお勧めします。 ### 値のデシリアライズ -`KRowMapper`は`java.sql.ResultSet`から値の取得を行うため、デフォルトではこの実装でサポートされていない型を取得することはできません。 -この問題に対応するため、`KRowMapper`ではデフォルトの変換機能に加え以下の3種類のデシリアライズ方法を提供しています。 +`KRowMapper`は`BeanPropertyRowMapper`同様`ConversionService`(デフォルトでは`DefaultConversionService.sharedInstance`)を用いたデシリアライズをサポートしています。 + +これに加え、より明示的で柔軟性の高いデシリアライズ方法として、`KRowMapper`では以下の3種類のデシリアライズ方法を提供しています。 1. `KColumnDeserializer`アノテーションを利用したデシリアライズ 2. デシリアライズアノテーションを自作してのデシリアライズ 3. 複数引数からのデシリアライズ +これらのデシリアライズ方法は`ConversionService`によるデシリアライズより優先的に適用されます。 + #### KColumnDeserializerアノテーションを利用したデシリアライズ 自作のクラスで、かつ単一引数から初期化できる場合、`KColumnDeserializer`アノテーションを用いたデシリアライズが利用できます。 `KColumnDeserializer`アノテーションは、コンストラクタ、もしくは`companion object`に定義したファクトリーメソッドに対して付与できます。 @@ -470,6 +476,3 @@ class Foo( val description: String = "" ) ``` - -#### Enumをデシリアライズする -DBに格納された値と`Enum::name`プロパティが一致する場合、特別な記述無しに`Enum`をデシリアライズすることができます。 From 44061df4980fa504581e658ba6632a6d7ebaccf4 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 25 Apr 2021 18:53:10 +0900 Subject: [PATCH 8/8] =?UTF-8?q?README=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index da68309..dba4780 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,9 @@ Also, it supports the default arguments which are peculiar to `Kotlin`. Also, by default, `KRowMapper` compares argument names and column names to see if they correspond. Therefore, in the case of "argument name is `camelCase` and column name is `snake_case`", it is necessary to pass a function that appropriately converts the naming convention of the argument name. +You can also pass a `ConversionService` for value conversion if needed. +If you don't pass it, `DefaultConversionService.sharedInstance` will be used as default. + ### Initialization from method reference(KFunction) You can initialize `KRowMapper` from `method reference(KFunction)` as follows It is. @@ -235,13 +238,16 @@ By using the contents described so far, you can perform more flexible and safe m In addition, by making full use of the abundant functions provided by `KRowMapper`, further labor saving is possible. ### Deserialization -Since `KRowMapper` gets the value from `java.sql.ResultSet`, by default it is not possible to get the type which is not supported by this implementation. -To deal with this problem, `KRowMapper` provides the following three types of deserialization methods in addition to the default conversion function. +`KRowMapper` supports deserialization using the `ConversionService` (`DefaultConversionService.sharedInstance` by default). + +In addition to this, as a more explicit and flexible deserialization method, `KRowMapper` provides the following three deserialization methods. 1. Deserialization by using the `KColumnDeserializer` annotation. 2. Deserialization by creating your own custom deserialization annotations. 3. Deserialization from multiple arguments. +These deserialization methods take precedence over deserialization by `ConversionService`. + #### Deserialization by using the KColumnDeserializer annotation If it is a self-made class and can be initialized from a single argument, deserialization using the `KColumnDeserializer` annotation can be used. `KColumnDeserializer` annotation can be used to `constructor` or `factory method` defined in `companion object`. @@ -481,6 +487,3 @@ class Foo( val description: String = "" ) ``` - -#### Deserialize Enum -If the value stored in the DB and the `Enum::name` property of the map destination are the same, it will be automatically converted to You can deserialize the `Enum`.