Android Room: error: setValue(T) has protected access in LiveData

Viewed 446

I'm trying to get up and running with Android development and Room.

I'm making a music player app with playlists and a file browser that will be able to add tracks to the current playlist.

I'm saving the playlists in a Room database.

I'm running into the problem of running the program from the first time, and there not being any data in the database.

I want to query the database for the last playlist opened, but if there are no playlists in the database, I want to create an empty PlayList object.

 7    public class PlayListRepository
 8    {
 9        public PlayListRepository(Application application)
10        {
11           _application = application;
12        }
13
14        public LiveData<PlayListWithTracks> getPlayList(int playListId)
15        {
16            if (_appDao == null) {
17                InitDb();
18            }
19            LiveData<PlayListWithTracks> livePlayListWithTracks = _appDao.getByIdWithTracks(playListId);
20            if (livePlayListWithTracks.getValue() == null) {
21                livePlayListWithTracks.setValue(new PlayListWithTracks());
22            }
23            return livePlayListWithTracks;
24        }
25
26
27        private void InitDb()
28        {
29            AppDatabase db = AppDatabase.getDatabase(_application);
30            _appDao = db.appDao();
31        }
32
33        private Application _application;
34        private AppDao _appDao;
35    }

Line 21 doesn't compile. It says error: setValue(T) has protected access in LiveData.

My AppDao.getByIdWithTracks method looks like this:

@Dao
public interface AppDao
{
    @Transaction
    @Query("SELECT * FROM PlayList WHERE Id = :id")
    LiveData<PlayListWithTracks> getByIdWithTracks(int id);
}

I've tried casting livePlayListWithTracks to MutableLiveData<PlayListWithTracks>, but that gives me a runtime error of androidx.room.RoomTrackingLiveData cannot be cast to androidx.lifecycle.MutableLiveData

I've tried casting it to RoomTrackingLiveData, but Android Studio doesn't recognize the androidx.room import.

Am I on the wrong track or what?

Edit: Here is PlayListWithTracks:

public class PlayListWithTracks
{
    @Embedded
    public PlayList playList;
    @Relation(
            parentColumn = "id",
            entityColumn = "playListId"
    )
    public List<Track> tracks = new Vector<Track>();
}
1 Answers

LiveData represents the data in your database. If you modify that entry in the database from any other part of your application your LiveData will reflect that change. It serves no purpose to try and set another value to the LiveData.

If you do not require to observe changes in the Data then you can probably return the object in the Data Access Object. Like so:

@Dao
public interface AppDao
{
    @Transaction
    @Query("SELECT * FROM PlayList WHERE Id = :id")
    PlayListWithTracks getByIdWithTracks(int id);
}

Perhaps the better approach would be to create a new playlist entry in the database if it does not exist and then access that entry. Meaning that you could add a new PlayListWithTracks entity to the database with the id received in the function and then access that entity

Related