android - How to access other classes data easily in Kotlin + Room (MVVM)? - Stack Overflow

admin2025-04-15  1

I'm working with Kotlin + Jetpack Compose. I'm also using Room, Hilt, MVVM, UiStates, etc.

I have an entity Game, an entity Round and an entity Turn.

The relationships between them are:

  • Game 1:N Round
  • Round 1:N Turn

When I am working in TurnViewModel for example, I need to get some info from the entity Game, sometimes I even need to update it. What is the most efficient way to do this?

It would be great to get it trough dot notation, something like this: currentTurn.round.game.some_game_field, but since I'm used to work with Odoo framework, I'm a newbie and I don't know how to do it, even if that's the best way to work here.

Currently my Turn entity looks like this:

@Entity(
    tableName = "turn",
    foreignKeys = [
        ForeignKey(
            entity = Round::class,
            parentColumns = ["id"],
            childColumns = ["roundId"],
            onDelete = ForeignKey.CASCADE
        ),
        ForeignKey(
            entity = Player::class,
            parentColumns = ["id"],
            childColumns = ["player1Id"],
            onDelete = ForeignKey.CASCADE
        ),
        ForeignKey(
            entity = Player::class,
            parentColumns = ["id"],
            childColumns = ["player2Id"],
            onDelete = ForeignKey.CASCADE
        )
    ]
)
data class Turn(
    @PrimaryKey(autoGenerate = true)
    val id: Long = 0,
    val roundId: Long,
    val player1Id: Long,
    val player2Id: Long,
)

data class TurnWithCards(
    @Embedded val turn: Turn,
    @Relation(
        parentColumn = "id",
        entityColumn = "id",
        associateBy = Junction(
            TurnCardRel::class,
            parentColumn = "turnId",
            entityColumn = "cardId"
        )
    )
    val cards: List<Card>
)

However, I find some problems here. If if create an object Turn, I only have the roundId which is a Long... Should I get the Game through DAO queries from the repository?

And on the other hand, I have the object TurnWithCards, which allows me to access easily to a list of object Card, but isn't there a way to have all data centralised in one object? I mean, maybe I need to add another list of objects, like Score for example, and should I create another data class TurnWithScores? Can't I have something like this?

data class TurnORM(
    ...
    val round: Round,
    val game: Game,
    val player1: Player,
    val player2: Player,
    val cards: List<Card>
)

If you see that this is a nosense, you can tell me, I only want to do this following good practice since I'm learning.

I'm working with Kotlin + Jetpack Compose. I'm also using Room, Hilt, MVVM, UiStates, etc.

I have an entity Game, an entity Round and an entity Turn.

The relationships between them are:

  • Game 1:N Round
  • Round 1:N Turn

When I am working in TurnViewModel for example, I need to get some info from the entity Game, sometimes I even need to update it. What is the most efficient way to do this?

It would be great to get it trough dot notation, something like this: currentTurn.round.game.some_game_field, but since I'm used to work with Odoo framework, I'm a newbie and I don't know how to do it, even if that's the best way to work here.

Currently my Turn entity looks like this:

@Entity(
    tableName = "turn",
    foreignKeys = [
        ForeignKey(
            entity = Round::class,
            parentColumns = ["id"],
            childColumns = ["roundId"],
            onDelete = ForeignKey.CASCADE
        ),
        ForeignKey(
            entity = Player::class,
            parentColumns = ["id"],
            childColumns = ["player1Id"],
            onDelete = ForeignKey.CASCADE
        ),
        ForeignKey(
            entity = Player::class,
            parentColumns = ["id"],
            childColumns = ["player2Id"],
            onDelete = ForeignKey.CASCADE
        )
    ]
)
data class Turn(
    @PrimaryKey(autoGenerate = true)
    val id: Long = 0,
    val roundId: Long,
    val player1Id: Long,
    val player2Id: Long,
)

data class TurnWithCards(
    @Embedded val turn: Turn,
    @Relation(
        parentColumn = "id",
        entityColumn = "id",
        associateBy = Junction(
            TurnCardRel::class,
            parentColumn = "turnId",
            entityColumn = "cardId"
        )
    )
    val cards: List<Card>
)

However, I find some problems here. If if create an object Turn, I only have the roundId which is a Long... Should I get the Game through DAO queries from the repository?

And on the other hand, I have the object TurnWithCards, which allows me to access easily to a list of object Card, but isn't there a way to have all data centralised in one object? I mean, maybe I need to add another list of objects, like Score for example, and should I create another data class TurnWithScores? Can't I have something like this?

data class TurnORM(
    ...
    val round: Round,
    val game: Game,
    val player1: Player,
    val player2: Player,
    val cards: List<Card>
)

If you see that this is a nosense, you can tell me, I only want to do this following good practice since I'm learning.

Share Improve this question asked Feb 4 at 12:02 forvasforvas 10.2k7 gold badges75 silver badges165 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

What you're trying to do can be done with @Relation and @Embedded annotations,
but it is useless, to reload values which may not have changed, to update the view.

Creating one huge joined query is commonly not what one would like to do, despite it's possible. It's probably more handy to have some GameState or RoundState class (not ORM, but eventually as ViewModel or ViewDataBinding), which holds the current values; I mean, not to directly map the values from ORM to the GUI; and for subsequent queries, one can obtain the IDs to query for or update from there. Sometimes it is useful to directly map ORM to the GUI, sometimes not.

The object modelling itself appears unfortunate and could possibly reduced.
One could even still nest the players into to game, or even dissolve game.

To provide an example of what I'm talking about:

class GameState(

    // cards nested into here, as they're being held by players.
    val players: ArrayList<Player>,

    // rounds nested into here, as a game is a series of rounds.
    val game: Game
)

Maybe take a piece of paper or a tablet PC and draw these object relations once.
Class TurnORM is certain proof that you may have missed this initial design step.
With ORM, the object design also dictates how the database would look alike.

转载请注明原文地址:http://www.anycun.com/QandA/1744721745a86707.html