The field's same name issue in the tables, when join tables in ROOM

拥有回忆 提交于 2019-12-30 15:46:14

问题


I'm using ROOM for my project. But I'm having trouble for joining between tables, because the tables have a same name fields.

for example, my project has tree tables, "word" & "favorite" & "bookmark", which has a same name fields.

1- word

@Entity(tableName = "word")
public class Word {

    @NonNull
    @PrimaryKey(autoGenerate = true)
    private int id;

    @NonNull
    private String title;
    private String mean;
    private String pronunciation;

    // Getter and Setter
}

2- favorite

@Entity(tableName = "favorite",
    foreignKeys = @ForeignKey(
            entity = Word.class,
            parentColumns = "id",
            childColumns = "word_id",
            onDelete = CASCADE,
            onUpdate = CASCADE))
public class Favorite {

    @NonNull
    @PrimaryKey
    private int word_id;
    private long time;

    // Getter and Setter
}

3- bookmark

     @Entity(tableName = "bookmark",
         primaryKeys = {"word_id", "category_id"},
         foreignKeys = {
            @ForeignKey(entity = Word.class,
                    parentColumns = "id",
                    childColumns = "word_id",
                    onDelete = CASCADE,
                    onUpdate = CASCADE)})
     public class Bookmark {
         @NonNull
         private int word_id;
         private long time;
         private int color;

        // Getter and Setter
}

To create a join between the three, I defined a new type called "WordAndFavoriteAndBookmark", and used "@Embedded" (as shown below). and to fix the same field problem, I used prefix as a Thomas Fischer response

4- WordAndFavoriteAndBookmark

   public class WordAndFavoriteAndBookmark {
    @Embedded
    private Word word;

    @Embedded(prefix = "favorite_")
    private Favorite favorite;

    @Embedded(prefix = "bookmark_")
    private Bookmark bookmark;

    //Getter and Setter
    public Word getWord() { return word; }
    public void setWord(Word word) {this.word = word;}    
    public Favorite getFavorite() { return favorite; }    
    public void setFavorite(Favorite favorite) { this.favorite = favorite;}    
    public Bookmark getBookmark() { return bookmark;  }    
    public void setBookmark(Bookmark bookmark) { this.bookmark = bookmark; }    
    }

To create a join between these tables I have defined a new @Dao.

 @Dao
public interface WordAndFavoriteAndBookmarkDao {
    @Query("SELECT word.*, favorite.time FROM word LEFT JOIN favorite " +
            "ON word.id = favorite.word_id")
    LiveData<List<WordAndFavoriteAndBookmark>> getAllWordsByFavoritesForLanguage();
    }

But again, after using the query, I encounter the error for the following code in my view(Activity or Fragment):

mWordAndFavoriteAndBookmark.getFavorite().getTime();

I think this is due to the use of Perfix, but I do not know the solution to this problem

EDITED: by Thomas Fisher answer, everything is fine. But when used "Count" or "Sum" in my query, I have problem for reading these values and I don't know how to read them.


回答1:


  1. You don't need a separate dao.

  2. Except for one plain, "@Embedded" annotation, the other annotations have to set a prefix: @Embedded(prefix = "favorite_") and @Embedded(prefix = "bookmark_")

  3. In your query, your selected fields have to have the prefix.

Instead of

select * from word join bookmark join favorite // pseudo code

You have to alias the fields to your prefix:

select word.*, bookmark.id as bookmark_id..., favorite.id as favorite_id... from...

This prevents the three id columns to override each other in the query. And with the prefix, the dao will expect all columns of that table to have that prefix in front of the actual column name.

Also what exact error do you get?

I'd guess there might be a NPE. That might have to do with your query. So if you can include the query as well, it would help find the issue.




回答2:


To solve the "Count" or "Sum" field problem, I used the new compound data class. As below:

public static class CategoryAndEssentials {
    @Embedded
    private BookmarkCategory bookmarkCategory;

    private int wordCount;

    public BookmarkCategory getBookmarkCategory() { return bookmarkCategory; }
    public void setBookmarkCategory(BookmarkCategory bookmarkCategory) { this.bookmarkCategory = bookmarkCategory;}
    public int getWordCount() { return wordCount; }
    public void setWordCount(int wordCount) { this.wordCount = wordCount; }
}

And in the query definition, in Dao class, I referred to this field:

@Query("SELECT " +
            "bookmarkCategory.*, " +
            "COUNT(bookmark.category_id) AS wordCount, " +
        "FROM bookmarkCategory LEFT JOIN bookmark " +
        "ON bookmarkCategory.id = bookmark.category_id " +
        "GROUP BY bookmarkCategory.id ")
LiveData<List<EntityClassForJoinTables.CategoryAndEssentials>> getAllCategoriesAndEssentials();

Note that the alias column in query must have a same as the variable defined in the compound data class



来源:https://stackoverflow.com/questions/51512556/the-fields-same-name-issue-in-the-tables-when-join-tables-in-room

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!