Why this Android Room insert does not work?
Asked Answered
C

1

12

I implemented caching with room but for some reason it got spoiled, either it does not insert or does not get the data, I've done lot of debugging though, but still no any clue... Can someone help with this? So, the picture is following:

MainActivity:

mArticleViewModel = ViewModelProviders.of(this).get(ArticleViewModel.class);
mArticleViewModel.getArticleList(mPageNumber).observe(this, articles 
-> { /* doesn't matter */ });

ViewModel:

public class ArticleViewModel extends AndroidViewModel {

    public static final String TAG = "ArticleViewModel";
    private LiveData<List<Article>> articleList;
    private ArticleRepository articleRepository;

    public ArticleViewModel(@NonNull Application application) {
        super(application);
        Log.d(TAG, "ArticleViewModel");
        if (articleRepository == null) {
            articleRepository = new ArticleRepository(application);
        }
    }


    public LiveData<List<Article>> getArticleList(int pageNumber) {
        Log.d(TAG, "getArticleList");
        articleList = articleRepository.getArticles();
        return articleList;
    }
}

Repository:

public class ArticleRepository {
        public static final String TAG = "ArticleRepository";
        public static final int PAGE_SIZE = 20;

        private ArticleDao mArticleDao;


    public ArticleRepository(Application application) {
        ArticleRoomDatabase db = 
    ArticleRoomDatabase.getInstance(application);
        mArticleDao = db.articleDao();
        loadArticles(1);
    }

    public void loadArticles(int page) {
        Log.d(TAG, "getArticles");



    //        ApiService.getService().getArticles("test", "thumbnail", page, 
        PAGE_SIZE).enqueue(new Callback<Example>() {
    //            @Override
    //            public void onResponse(Call<Example> call, 
        Response<Example> response) {
    //                Log.d(TAG, "onResponse");
    //                if (response.isSuccessful()) {
    //                    Log.d(TAG, "isSuccessful");
    //                    List<Article> articles = 
        pojoToEntity(response.body().getResponse().getResults());
    //                    populateDb(articles);
    //                }
    //            }
    //
    //            @Override
    //            public void onFailure(Call<Example> call, Throwable t) {
    //                Log.d(TAG, "onFailure: " + t.getStackTrace());
    //            }
    //        });

    //My web service is not available currently, so I use dummy data
        populateDb(DummyData.populateData());
    }

    public LiveData<List<Article>> getArticles() {
        LiveData<List<Article>> articles  =  mArticleDao.getAllArticles();
        return articles;
    }

    public void populateDb(List<Article> articles) {
        Log.d(TAG, "populateDb");
        Article[] articleArray = new Article[articles.size()];
        for (int i = 0; i < articles.size(); i++) {
            articleArray[i] = articles.get(i);
        }

        new insertAsyncTask(mArticleDao).execute(articleArray);
    }


    public List<Article> pojoToEntity(List<Result> resultList) {
        List<Article> articles = new ArrayList<>();
        for (Result result : resultList) {
            Article article = new Article();
            article.setSectionName(result.getSectionName());
            article.setWebTitle(result.getWebTitle());
            article.setThumbnail(result.getFields().getThumbnail());
            articles.add(article);
        }
        return articles;
    }


    private static class insertAsyncTask extends AsyncTask<Article, Void, Void> {

        private ArticleDao articleDao;

        public insertAsyncTask(ArticleDao articleDao) {
            this.articleDao = articleDao;
        }

        @Override
        protected Void doInBackground(Article... articles) {
            Log.d(TAG, "doInBackground");
            articleDao.insertAll(articles);
            return null;
        }
    }
}

Entity with getter setter methods which I didn't copy of course:

@Parcel(Parcel.Serialization.BEAN)
@Entity(tableName = "articles")
public class Article {

@NonNull
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "uid")
private int uid;

@ColumnInfo(name = "section_name")
private String sectionName;

@ColumnInfo(name = "title")
private String webTitle;

@ColumnInfo(name = "image_url")
private String thumbnail;

DAO:

@Dao
public interface ArticleDao {

    @Insert
    void insertAll(Article... articles);

    @Query("DELETE FROM articles")
    void deleteAll();

    @Query("SELECT * FROM articles")
    LiveData<List<Article>> getAllArticles();
}    

RoomDatabase:

@Database(entities = {Article.class}, version = 1, exportSchema = false)
public abstract class ArticleRoomDatabase extends RoomDatabase {

    public static String TAG = "ArticleRoomDatabase";

    private static ArticleRoomDatabase INSTANCE;

    public static ArticleRoomDatabase getInstance(final Context context) {
        if (INSTANCE == null) {
            synchronized (ArticleRoomDatabase.class) {
                if (INSTANCE == null) {
                    INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                            ArticleRoomDatabase.class, "photo_database")
                            .build();
                }
            }
        }
        return INSTANCE;
    }

    public abstract ArticleDao articleDao();
}

As far as Logging shows, getting articles from DB fails, the list is returned null, however, in real I can't get if inserting fails or getting... tried to debug but could not get anything.

Coating answered 25/6, 2018 at 17:36 Comment(7)
did you solve the problem? I have same issue.Mcmillon
@MirjalalTalishinski unfortunately no, I just added common List to Room, but I still wonder why it doesn't work with LiveData. So, if you find an answer please shareCoating
actually I also posted a question with the same problem. I posted it here. https://mcmap.net/q/1012019/-room-does-not-insert-data-to-tableMcmillon
I think I know the problem where happens, well it is all about the insert section. If you want we can get into the deep about that.Mcmillon
@MirjalalTalishinski I am on another task currently, but I will get back to you as soon as I canCoating
Sure, at this time I will try to solve the problem.Then I will return to you.Mcmillon
Well, I solved my problem. The problem was about the AsyncTask execution. I'm using Java so I will try to explain the solution in Java. There is a special executor dor AsyncTask, which named as *THREAD_POOL_EXECUTOR. I changed my code from new MyAsyncTask().execute(); to new MyAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);. That piece of code solved my problem.Mcmillon
E
5

First verify that insert is working or not. You can get list of all inserted row by below DAO method

Add below method in your DAO

@Insert
fun insertAll(articleList : List<Article>) : List<Long>

this method will return list of uid (primarykey).

That way you can verify data are inserted or not.

Once it is working let me know i will help you out with getAllData()

Easily answered 11/7, 2019 at 9:32 Comment(3)
he is talking in javaTreulich
@coroutineDispatcher : language don't matter i am providing way.Easily
App Inspection can be used now instead of this.Aligarh

© 2022 - 2024 — McMap. All rights reserved.