Reputation: 840
I am working on a small project using Room. Basically a Recipe can have many Ingredients and an Ingredient can belong to many Recipes.
These are my Entities as the Documentation in the many-to-many relationship part suggested:
@Entity
data class Recipe(
var name: String
) {
@PrimaryKey(autoGenerate = true)
var recipeUID: Int = 0
}
@Entity
data class Ingredient(
var name: String
) {
@PrimaryKey(autoGenerate = true)
var ingredientUID: Int = 0
}
@Entity(primaryKeys = ["recipeUID", "ingredientUID"])
data class RecipeIngredientCrossRef(
val recipeUID: Int,
val ingredientUID: Int
)
//Docs suggested @Junction but that causes error for using tag inside @Relation...
data class RecipeWithIngredients(
@Embedded
val recipe: Recipe,
@Relation(
parentColumn = "recipeUID",
entity = Ingredient::class,
entityColumn = "ingredientUID",
associateBy = Junction(
value = RecipeIngredientCrossRef::class,
parentColumn = "recipeUID",
entityColumn = "ingredientUID"
)
)
var ingredients: List<Ingredient>
)
Then I tried to make the Dao functions following the same documentation but it only describes how to retrieve, which I applied here:
@Transaction
@Query("SELECT * FROM recipe")
suspend fun getAllRecipes(): List<RecipeWithIngredients>
Then I found this Medium article explaining what I wanted to achieve, which lead me to write this for the Insert function:
@Insert(onConflict = REPLACE)
suspend fun insert(join: RecipeIngredientCrossRef): Long
Everything works up to the insertion, I have verified that the info is being inserted, however I am doing something wrong in retrieving since it returns nothing. I can see that the reason it returns nothing is because there was nothing inserted into that table (as my insert method places it into the RecipeIngredientCrossRef table and not the recipe table), which leads me to believe the part that is wrong is in fact my insertion method.
So basically my question is: How can I retrieve a list of RecipeWithIngredients object that contains a recipe object with a list of ingredient objects as a member variable?
The documentation on Room CRUD functionality does not mention anything about this type of relationships.
I have been looking for hours on Youtube, here, the documentation and Medium but so far nothing has worked. Can someone please shed some light or point me in the right direction.
Upvotes: 0
Views: 819
Reputation: 5103
Haven't you forgot to add insert-methods for your Recipe
and Ingredient
tables?
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertRecipe(recipe: Recipe): Long
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertIngredient(ingredient: Ingredient): Long
So to get unempty RecipeWithIngredients
result there should be three tables filled with data with your inserts from dao - Recipe
, Ingredient
, RecipeIngredientCrossRef
. And of course they should contain id-s, that match to each other.
Upvotes: 2