JPA の Entity
では単一キーである id
列を持たせるような構造を定義することが出来るが SQLite の INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT
な列に関して適切な定義がよく分からなかったのでメモ。
例えば以下のようなテーブルがあるとする:
create table comments (
id integer not null primary key autoincrement,
name varchar(16) not null,
body text not null,
created datetime not null,
modified datetime not null,
);
このような AUTOINCREMENT
な PRIMARY KEY
があると SQLite は内部的に sqlite_sequence
というテーブルに各テーブルのシーケンスを格納するという挙動をする。
sqlite_sequence
テーブルの DDL は以下のようになっている:
CREATE TABLE sqlite_sequence (name, seq);
name
にはテーブル名、seq
には現在のシーケンス値が格納される。
この sqlite_sequence
テーブルを Hibernate 側に教えてやればよい。
この場合の Entity
定義は以下のようになる:
@Entity
@Table(name = "comments")
data class Comment(
@Id
@GeneratedValue(generator = "sqlite_comments") // Generator 名 (何でもよい)
@TableGenerator(
name = "sqlite_comments", // @GeneratedValue.generator と合わせる
table = "sqlite_sequence", // SQLite のシーケンステーブル名と合わせる
pkColumnName = "name", // sqlite_sequence のシーケンスカラム名 (name 固定)
valueColumnName = "seq", // sqlite_sequence のシーケンス値名 (seq 固定)
pkColumnValue = "comments", // sqlite_sequence.name に格納されている値 (テーブル名)
initialValue = 1, // シーケンス初期値. 多くの場合 1
allocationSize = 1 // AUTO INCREMENT される場合の増減値. 何故かデフォルト 50 になっているので 1 を指定する
)
var id: Int? = null,
var name: String = "",
var body: String = "",
@CreatedDate var created: Date = Date(),
@LastModifiedDate var modified: Date = Date()
)