ActiveAndroidで事前にdbを用意した場合にPK列を指定する方法


ActiveAndroidはModelだけ記述していけば、初回にテーブルも作ってくれますが
今回は事前にdbファイルを用意してassets配下に置いた場合の話

その際の注意事項として

PKをidにリネームしてください

公式wikiには書かれています

が、めんどいって思ったのでなんか対応方法無いか探ってみました

Tableアノテーションで指定可能だったりする?

他のORMでいくとテーブルの設定のとこでPK列の指定もできるので
そこら辺りのソースをみてたら、それっぽいのがありました

ってことで、一応TableアノテーションでPKの列指定は可能っぽい

Item.java

@Table(name = "items", id = "item_id")
public class Item extends Model {

    @Column(name = "item_id", notNull = true)
    public int itemId;  // PK

    @Column(name = "name", notNull = true)
    public String name;
}

これで大丈夫そうです
item.getId()でもitem.itemIdでも同じ値が返ってきます

この指定をせずにitem.save()とかすると、
insert文に自動的にId列が付加されて、
そんな列名ありませんエラーで落ちます

指定した列がA/Iの場合

今回の例でいうとitem_idauto increment設定だった場合です
上記のModel設定のまま

sample.java

Item item = new Item();
item.name = "hoge";
item.save();

Item item2 = new Item();
item2.name = "hogehoge";
item2.save();

という感じで保存すると、発行される1回目のsqlは
insert into items (item_id, name) values (0, "hoge");
という感じ
そして2回めは
insert into items (item_id, name) values (0, "hogehoge");
となってauto incrementが効きません
(なので、上記例は2回目でpriamry違反で落ちます)

ということでちょっとModel設定を変える必要があります

Item.java

@Table(name = "items", id = "item_id")
public class Item extends Model {

    // notnull制約を外して、nullを持てるようにintからIntegerへ
    @Column(name = "item_id", notNull = false)
    public Integer itemId;  // PK

    @Column(name = "name", notNull = true)
    public String name;
}

こういう設定をして先ほどのように保存すると
ちゃんとauto incrementが有効になります

ただ、いくらModel上の話とはいえ…
PK列なのにnot null制約を外してnull保持できるようにするっていうことになって
凄く気持ち悪いので、公式wikiがかいてあるとおり、idにリネームするほうが良い気がします(笑)
(結局内部でもidはそんな扱いにしてそうだけど。。。)

まぁauto incrementじゃないとか、PKが整数じゃないとかっていう変なテーブルなんかでは
TableアノテーションでPK名指定できるっていうのは有用な感じですか。。

参考

ActiveAndroid
ActiveAndroid - wiki
ActiveAndroidのWikiを和訳した - Qitta @hotchemi さん


なにか間違いなどあれば、指摘下さるとありがたいです〜