一応、備忘録として。
前提
事象
@Transactionalを付与したメソッドの戻り値をList<Map<String, String>にすると、
ジェネレートされたクラス側でコンパイルエラー
実際のコードは、以下のような感じ。
@Transactional public List<Map<String, String>> select(SQLiteDatabase db, SQLDomain domain) { Cursor c = db.query(domain.getTableName(), ...); boolean roop = c.moveToFirst(); String columnNames[] = c.getColumnNames(); List<Map<String, String>>resultList = new ArrayList<Map<String, String>>(); while(roop) { Map<String,String> resultMap = new HashMap<String, String>(); for(String columnName : columnNames) { resultMap.put(columnName, c.getString(c.getColumnIndexOrThrow(columnName))); } resultList.add(resultMap); roop = c.moveToNext(); } c.close(); return resultList; }
これに対して、ジェネレートされるクラスでは
import java.util.List<java.util.Map<java.lang.String,java.lang.String>>; @Override public List<Map<String, String>> select(final SQLiteDatabase db, final SQLDomain domain) { db.beginTransaction(); try { String>>result_ = AttendanceManagementDao_.super.select(db, domain); db.setTransactionSuccessful(); return result_; } catch (RuntimeException e) { Log.e("AttendanceManagementDao_", "Error in transaction", e); throw e; } finally { db.endTransaction(); } }
このような感じ。
インポート文とローカル変数宣言に失敗している。
ジェネリクスがらみでとことん失敗してしまうようだ。
ローカル変数としてジェネリクスを利用する分には問題なさそうなのだが、
戻り値にList<Map<String, String>>を指定したのが良くなかったぽい。
回避策
アノテーションスコープ(@Transactional)内でジェネリクスを使わない。
手法としては、2通り思いついた。
1.List<Map<String, String>を内包するクラスを作る
2.そもそもジェネリクスを使わない(>_<)
2は悲しいので、1を採用しました。
こんな感じ。
package com.yank.yy.dao; import java.util.ArrayList; import java.util.List; import java.util.Map; public class DBResult { private List<Map<String,String>> resultList = new ArrayList<Map<String,String>>(); public List<Map<String, String>> get() { return resultList; } public void add(Map<String,String> map) { resultList.add(map); } }
まとめ
AndroidAnnotations便利だけど、これに関してはちょっとびっくりした。ていうかウケたw
ソース解析してコンパイル時にクラスを生成するので、その想定パターン外だったのだろう。
GoogleさんにIssue出せば直してくれるかな。
AndroidAnottations、よく考えられている仕組みなので、皆さん使ってみてください。
0 件のコメント:
コメントを投稿