Search code examples
androidandroid-roomandroid-livedataandroid-cursor

error: Not sure how to convert a Cursor to this method's return type (com.madstone.tageditor.database.TrackFileAndSong)


I'm getting the error following error when building the project in android studio

error: Not sure how to convert a Cursor to this method's return type (com.madstone.tageditor.database.TrackFileAndSong). LiveData<List> getTrackFileAndSong();

I'm trying to fetch related TrackFile and Song objects from a room database using an intermediate data class TrackFileAndSong and store the returned object as LiveData

TrackFile:

@Entity(tableName = "track_file_table")
public class TrackFile {
    @PrimaryKey(autoGenerate = true)
    public long id;

    @ColumnInfo(name = "track_name")
    public String trackFileName;

    @ColumnInfo(name = "track_path")
    public String trackFilePath;
}

Song:

@Entity(tableName = "song_table")
public class Song {

    @PrimaryKey(autoGenerate = true)
    public long songId;

    @ColumnInfo(name = "Title")
    public String songTitle;

    @ColumnInfo(name = "Artist")
    public String songArtist;

    @ColumnInfo(name = "Album Artist")
    public String songAlbumArtist;

    @ColumnInfo(name = "Album")
    public String songAlbum;

    @ColumnInfo(name = "Year")
    public String songYear;

    public long fileId;

}

TrackFileAndSong:

public class TrackFileAndSong {
    @Embedded
    public TrackFile trackFile;
    @Relation(
            parentColumn = "id",
            entityColumn = "fileId"
    )
    public Song song;
}

The error is thrown at this query

    @Transaction
    @Query("SELECT * FROM song_table ORDER BY Title ASC")
    LiveData<List<TrackFileAndSong>> getTrackFileAndSong();

Any help would be appreciated


Solution

  • The reason is that you are saying something along the lines of:-

    From the song_table get the List of TrackFileAndSong, which equates to get all the TrackFiles (parents aka Embedded) from the song_table (and then get the song from the song_table the children aka @Relation)

    • Obviously there are no TrackFiles in the song_table (so Room is confused as you are telling to to get a TrackFile from a row in the song_table).

    So to use TrackFileAndSong then you should be using FROM track_file_table of course there is no Title column for the ORDER BY clause.

    So the following would at least circumvent the error:-

    @Transaction
    @Query("SELECT * FROM track_file_table")
    LiveData<List<TrackFileAndSong>> getTrackFileAndSong();
    

    However, it might be that you really want (for example)

    class SongAndTrackFile {
       @Embedded
        Song song;
        @Relation(
                entity = TrackFile.class,
                parentColumn = "fileId",
                entityColumn = "id"
        )
        TrackFile trackFile;
    }
    
    • i.e. the @Embedded (the parent) and the @relation (the child) have been swapped.

    in which case the following would work:-

    @Transaction
    @Query("SELECT * FROM song_table ORDER BY Title ASC")
    LiveData<List<SongAndTrackFile /*!!!!!<<<<< NOTE CHANGED Type!!!!!*/>> getSongAndTrackFile();
    
    • obviously you wouldn't need the comment added just to indicate the change from the original