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,
);

このような AUTOINCREMENTPRIMARY 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()
)