自動採番されるプライマリキー

mirage-scalaではエンティティを使用してレコードのINSERTを行う際にDB側で自動採番されるプライマリキーの場合、以下のようにJavaのラッパー型で宣言しておいてnullをセットするか、

@Table(name="BOOK")
case class Book(
  @(PrimaryKey @field)(generationType = IDENTITY)
  bookId: java.lang.Long,
  bookName: String,
  author: String)

val book = Book(null, "Mirage in Action", "Naoki Takezoe")
sqlManager.insertEntity(book)

Option型で宣言しておいてNoneをセットする必要がありました。どちらも非常に行けてないですね。

@Table(name="BOOK")
case class Book(
  @(PrimaryKey @field)(generationType = IDENTITY)
  bookId: Option[Long],
  bookName: String,
  author: String)

val book = Book(None, "Mirage in Action", "Naoki Takezoe")
sqlManager.insertEntity(book)

というわけでOptionの代わりにPkという型でラップできるようにしてみました。INSERTする場合はAutoを指定します。

@Table(name="BOOK")
case class Book(
  @(PrimaryKey @field)(generationType = IDENTITY)
  bookId: Pk[Long],
  bookName: String,
  author: String)

val book = Book(Auto, "Mirage in Action", "Naoki Takezoe")
sqlManager.insertEntity(book)

アプリ側で採番した値でINSERTする場合はこんな感じにします。

@Table(name="BOOK")
case class Book(
  @(PrimaryKey @field)(generationType = APPLICATION)
  bookId: Pk[Long],
  bookName: String,
  author: String)

val book = Book(Id(1), "Mirage in Action", "Naoki Takezoe")
sqlManager.insertEntity(book)

ちなみにPk型からはgetメソッドで値を取得することができます。

val book = sqlManager.findEntity[Book](1)
// プライマリキーの値を取得
val bookId: Long = book.bookId.get

Pk型のプロパティはプライマリキーにマッピングするカラムであることは明白なのでうまいことやれば@PrimaryKeyアノテーションの指定も不要にできるかもしれません。