I have the following structure to define meetings with friends. First i have my Friend entity
@Entity(tableName = Friend.TABLE_NAME)
data class Friend(
@PrimaryKey(autoGenerate = true)
val id: Int? = null,
val alias: String? = null
) {
companion object {
const val TABLE_NAME = "friends"
}
}
Also have my Meeting entity
@Entity(tableName = Meeting.TABLE_NAME)
data class Meeting(
@PrimaryKey(autoGenerate = true)
val id: Int?,
val friendId: Int?,
val date: LocalDateTime?
) {
companion object {
const val TABLE_NAME = "meetings"
}
}
and then a helper class to relate them:
data class FriendMeetings(
@Embedded
val friend: Friend= Friend(),
@Relation(
parentColumn = "id",
entityColumn = "friendId"
)
val meetings: List<Meeting>
)
Also defined a type converter for the LocalDateTime field
class AppConverters {
@TypeConverter
fun fromLocalDateTime(date: LocalDateTime?): Long? =
date?.toMillis()
@TypeConverter
fun toLocalDateTime(millisSinceEpoch: Long?): LocalDateTime? =
if (millisSinceEpoch == null) {
null
} else LocalDateTime.ofInstant(
Instant.ofEpochMilli(millisSinceEpoch),
ZoneId.systemDefault()
)
}
When i ask in the dao for the list of all friends it works charmly
@Query("SELECT * FROM friends ORDER BY id")
fun getAll(): List<FriendMeetings>
If i ask in the dao for the meetings with a friend in an given date it works charmly
@Query("SELECT * FROM friends INNER JOIN meetings ON friends.id = meetings.friendId WHERE friends.id = :id AND meetings.date BETWEEN :startOfDay AND :endOfDay")
fun getMeetingsWithFriendBetweenDates(id: Long, startOfDay: Long, endOfDay: Long): FriendMeetings?
but if i try to get all meetings in a given date the results are not correct
@Query("SELECT * FROM friends INNER JOIN meetings ON friends.id = meetings.friendId WHERE meetings.date BETWEEN :startOfDay AND :endOfDay")
fun getMeetingsBetweenDates(startOfDay: Long, endOfDay: Long): List<FriendMeetings>?
In this case i get the correct number of friends but the friend data is repeated all over while the meetings are correct. I just thought that, as the meetings in a day wouldnt be many, i could just load the meetings and then for each one load the friend but seems a little bit nasty but i cant figure out whats wrong here
When an
@Relationis acted upon by Room, it will return ALL children of the respective parent and in an arbitrary order . That is the@Queryis only used to ascertain the parents, the underlying@Relationsare built by an underlying query that takes no parameters.What you need to do is bypass/override Room's convenience handling. This can be achieved by using a function with a body that controls both factors:-
So I believe that your solution for ALL
Friends but withMeetings BETWEEN a provided start and end date could be to have the following functions in an@Daointerface or abstract class:-@Query("")is to get Room to apply the@Transactionto the functionYou could utilise your existing
getAllfunction and just lose/discard the meetings (or programmatically extract the required meetings (noting that ALL meetings per a parent would exist)). e.g.