Closed9

[Kotlin] KomapperでEmbedded Valueをサポートするか検討

nakamura_tonakamura_to

Komapperでの実現案。KomapperEmbeddedアノテーションを導入する。

data class PersonInfo(
    val name: String,
    val age: Int
)

@KomapperEntity
data class Person(
    @KomapperId @KomapperAutoIncrement
    val id: Int = 0,
    @KomapperEmbedded
    val info: PersonInfo
)

組み込まれる側に@KomapperId@KomapperVersion等を付けるのはサポート外としたい。それをサポートすると実装する側も利用する側も大変すぎる。プレーンなValue Objectのまま使いたいニーズの方が強いのでないか?

nakamura_tonakamura_to

ただ複合主キーをEmbedded Valueで表現したいとなるとKomapperEmbeddedアノテーションとは別にKomapperEmbeddedIdアノテーションが必要か?

data class PersonId(
    val id1: String,
    val id2: Int
)

data class PersonInfo(
    val name: String,
    val age: Int
)

@KomapperEntity
data class Person(
    @KomapperEmbeddedId
    val id: PersonId,
    @KomapperEmbedded
    val info: PersonInfo
)
nakamura_tonakamura_to

クエリを書くときはEmbedded Valueの末端のプロパティに対して条件を指定できるようにする。そういうメタモデルを作らないといけない。

val p = Meta.persion
val query = QueryDsl.from(p).where { p.info.name eq "Jhon" }
nakamura_tonakamura_to

クエリのselectにEmbedded Valueのプロパティを指定してEmbedded Valueのインスタンスを直接取得可能とするかは要検討。

val p = Meta.persion
val query: Query<List<PersonInfo>> = QueryDsl.from(p).where { p.info.name eq "Jhon" }.select(p.info)
val infoList: List< PersonInfo > = db.runQuery(query)

上記は一見シンプルで良いが、下記のように一度エンティティで取得してからmapすれば同じことが実現できる。

val query: Query<List<Person>> = QueryDsl.from(p).where { p.info.name eq "Jhon" }
val people: List<Person> = db.runQuery(query)
val infoList: List<PersonInfo> = people.map { it.info }
nakamura_tonakamura_to

Spring Data JDBCのドキュメントにある@Embedded.onEmptyの機能はKotlinのnullabilityで表現できそう。

Spring Data JDBCのドキュメント:

class MyEntity {

    @Id
    Integer id;

    @Embedded(onEmpty = USE_NULL) 
    EmbeddedEntity embeddedEntity;
}

Komapperで表現するとしたら:

@KomapperEntity
data class MyEntity(
    @Id
    val id: Int,
    @KomapperEmbedded
    val embeddedEntity: EmbeddedEntity?
)
nakamura_tonakamura_to

同じ型のEmbedded Valueが1つのEntityに複数存在する場合を考慮しないといけない

@KomapperEntity
data class Person(
    @KomapperEmbeddedId
    val id: PersonId,
    @KomapperEmbedded
    val info1: PersonInfo,
    @KomapperEmbedded
    @KomapperAttributeOverride(...)
    val info2: PersonInfo
)
このスクラップは2022/08/10にクローズされました