3

Let's say I have an Ingredient entity, and a Recipe entity. Lots of recipes might refer to the same ingredient.

recipe 1 uses ingredients 1, 2 and 3
recipe 2 uses ingredients 1, 3 and 5

I want to be able to load the ingredients from the recipe, but not the reverse.

I think I need to model this as a Many-To-Many relation by creating a separate entity to track all the recipe <-> ingredient mappings.

Is my understanding correct, or is there some way to make this work with a ToMany relation?

I don't think using a single ToMany relation will work, because GreenDao requires them to have a foreign key in the target entity back to the original entity (see "Modelling To-Many Relations" in the docs). This means that ingredients can only refer to a single recipe - as soon as two recipes reference the same ingredient then one of them will lose its relation.

FTR, if you don't set up the foreign key in the target entity, then the ToMany relation is lost after restarting the application (i.e. it only works for the current database session). Tip: to simulate this scenario in your automated tests, just call daoSession.clear() before loading the object and asserting that it contains the values you expect.

Dan J
  • 25,433
  • 17
  • 100
  • 173
  • What you're describing sounds like a many to many relationship. You'll need to model this with an entity that holds this relationship. You can see this answer which talks about modeling a many to many relationship: http://stackoverflow.com/a/14837390/1163156 – mweathers Jun 08 '14 at 22:37

1 Answers1

0

Since one ingredient can be part of many recipes and one recipe consists of many ingredients this relation is clearly a many-to-many relation.

The common way to model this in your db is to store the relation in a separate table.

This is independent of the use of greendao. To achieve this model using greendao you will have to create a new entity RecipeToIngredient and build your relations using this entity.

Update

If you are free in designing your database you can use a schema like this:

Table IngredientType
--------------------------
id          | integer (pk)
description | text

Table Recipe
--------------------------
id          | integer (pk)
description | text

Table Ingredient
--------------------------
id_recipe   | integer (fk)
id_type     | integer (fk)
unit        | text
quantity    | integer

This means a toMany-relation from Ingredient to Recipe and from Igredient to IngredientType. Technically this is also a Many2Many-Mapping with additional attributes between IngredientType and Recipe.

In greendao you would use two toMany-relations to model this.

AlexS
  • 5,295
  • 3
  • 38
  • 54
  • Since ingredients don't need to know what recipes they are in, I was hoping there might be a way in GreenDao to treat this as a simple ToMany relation (i.e. just using GreenDao to lazy load the ingredients from IDs in the recipes, but not the reverse). I'm tempted to just store the ingredient IDs in the recipe and add a custom `getIngredients()` method to load them on demand. It looks like I'm deviating from the expected GreenDao use cases though. :-) – Dan J Jun 10 '14 at 18:28
  • @DanJ As I tried to explain this is not a greendao issue. For modelling a Many2Many you need a join-table. It doesn't matter whether you want your ORM-layer to have a bidirectional or unidirectional lookup. – AlexS Jun 10 '14 at 19:40