Yoshiyasu KO

Roomを実装したら、DataBindingのビルドエラーが起きたお話

2020-04-07

先日、Roomを使った検索履歴機能を実装していた時のお話。

Roomのドキュメントに沿って、

1. Entityを実装

@Entity(tableName = "search_keyword_history")
data class SearchKeywordHistoryEntity(
    @PrimaryKey(autoGenerate = true) val id: Long = 0,
    val keyword: String,
    val createdAt: Long = System.currentTimeMillis(),
    var updatedAt: Long = System.currentTimeMillis()
)

2. DAO(Database Access Object)を実装

@Dao
interface SearchKeywordHistoryDao {

    @Insert
    suspend fun insert(entity: SearchKeywordHistoryEntity)

    @Update
    suspend fun update(entity: SearchKeywordHistoryEntity)

    @Query("DELETE FROM search_keyword_history WHERE keyword LIKE :keyword")
    suspend fun deleteKeyword(keyword: String)

    // キーワードを降順で取得する
    @Query("SELECT keyword FROM search_keyword_history ORDER BY updatedAt DESC")
    suspend fun getKeywords(): List<SearchKeywordHistoryEntity>

    // クエリに部分一致するキーワードを降順で取得する
    @Query("SELECT keyword FROM search_keyword_history WHERE keyword LIKE '%' || :keywordQuery || '%' ORDER BY updatedAt DESC")
    suspend fun getKeywords(keywordQuery: String): List<SearchKeywordHistoryEntity>

    // クエリに完全一致するキーワードを見つける
    @Query("SELECT keyword FROM search_keyword_history WHERE keyword LIKE :keywordQuery LIMIT 1")
    suspend fun getKeyword(keywordQuery: String): SearchKeywordHistoryEntity?

}

3. Databaseを実装

@Database(entities = [SearchKeywordHistoryEntity::class], version = 1)
abstract class SearchHistoryDatabase : RoomDatabase() {
    abstract fun searchKeywordHistoryDao(): SearchKeywordHistoryDao
}

さて、ロジックは実装できたので、一旦ビルドしましょう。

ところがビルドエラーが発生。 以下ログ。

> Task :app:kaptStagingDebugKotlin
e: hogeBinding.java:32: エラー: シンボルを見つけられません

e: fugaBinding.java:57: エラー: シンボルを見つけられません

e: hogehogeBinding.java:68 エラー: シンボルを見つけられません
                
e: fugafugaBinding.java:77 エラー: シンボルを見つけられません

    ~ 略 ~

...?
DataBindingでシンボル未解決エラー?
特にレイアウトやバインドする変数を改変した覚えはないのだが...

その後も原因究明に徹するもレイアウトファイルに異常はなく。
Logcatにもヒントがなく、いよいよ良く分からんな...と匙をぶん投げていた。

そして何気なくコードを眺めていたらふと気付く。

    /** SearchKeywordHistoryDao.kt **/

    // キーワードを降順で取得する
    @Query("SELECT keyword FROM search_keyword_history ORDER BY updatedAt DESC")
    suspend fun getKeywords(): List<SearchKeywordHistoryEntity>

    // クエリに部分一致するキーワードを降順で取得する
    @Query("SELECT keyword FROM search_keyword_history WHERE keyword LIKE '%' || :keywordQuery || '%' ORDER BY updatedAt DESC")
    suspend fun getKeywords(keywordQuery: String): List<SearchKeywordHistoryEntity>

    // クエリに完全一致するキーワードを見つける
    @Query("SELECT keyword FROM search_keyword_history WHERE keyword LIKE :keywordQuery LIMIT 1")
    suspend fun getKeyword(keywordQuery: String): SearchKeywordHistoryEntity?

あれ、Query文間違ってね?
SELECT keywordだとEntityを取得できないからEntity返せないですね。

これを正しくEntityを返せるように、Query文を書き直し。

    /** SearchKeywordHistoryDao.kt **/

    // キーワードを降順で取得する
    @Query("SELECT * FROM search_keyword_history ORDER BY updatedAt DESC")
    suspend fun getKeywords(): List<SearchKeywordHistoryEntity>

    // クエリに部分一致するキーワードを降順で取得する
    @Query("SELECT * FROM search_keyword_history WHERE keyword LIKE '%' || :keywordQuery || '%' ORDER BY updatedAt DESC")
    suspend fun getKeywords(keywordQuery: String): List<SearchKeywordHistoryEntity>

    // クエリに完全一致するキーワードを見つける
    @Query("SELECT * FROM search_keyword_history WHERE keyword LIKE :keywordQuery LIMIT 1")
    suspend fun getKeyword(keywordQuery: String): SearchKeywordHistoryEntity?

そして何となくビルド。

えっ...うそ...やだ...通った...

原因はQuery文のミスでした。

ログも汎用的なBindingのシンボル未解決エラーだったし、こんなの気づくわけないよ...うん...というわけで今回備忘録的に記事を書きました。

まとめ

  • Roomを実装してビルドしたら、なぜかDataBindingのシンボル未解決エラーが起きたよ。
  • 探ってみたらQuery文のミスだったよ。
  • 何でシンボル未解決エラーが起きるのか、書いてる奴は分かってないよ。(知ってる人教えて)

参考になる方がいらっしゃれば幸いです。

じゃ、そゆことで。