I am implementing an android application with Room database and have a small question about relationships in this DB.
I have two tables:
@Entity(tableName = "foods", primaryKeys = {"id", "language_id"},
indices = {@Index(value = {"id", "language_id"}, unique = true)},
inheritSuperIndices = true)
public class Food {
@NonNull
@ColumnInfo(name = "id")
private String mId;
@NonNull
@ColumnInfo(name = "language_id")
private String mLanguageId;
}
@Entity(tableName = "ingredients", primaryKeys = {"id", "language_id"},
indices = {@Index(value = {"id", "language_id"}, unique = true),
@Index(value = {"food_id", "food_language_id"}, unique = true)},
foreignKeys = {@ForeignKey(entity = Food.class, parentColumns ="id",
childColumns = "food_id", onUpdate = CASCADE, onDelete = CASCADE),
@ForeignKey(entity = Food.class, parentColumns = "language_id",
childColumns = "food_language_id", onUpdate = CASCADE, onDelete =
CASCADE)},
inheritSuperIndices = true)
public class Ingredient {
@NonNull
@ColumnInfo(name = "id")
private String mId;
@NonNull
@ColumnInfo(name = "language_id")
private String mLanguageId;
@ColumnInfo(name = "food_id")
private String mFoodId;
@ColumnInfo(name = "food_language_id")
private String mFoodLanguageId;
}
The both tables 'Food' and 'Ingredient' have composite primary keys ('id', 'language_id'). The Food object has to contains a List and of course a @Relationship
public class FoodWithIngredients extends Food{
@Relation(parentColumn = "id", entityColumn = "food_id", entity =
Ingredient.class)
private List<Ingredient> mIngredients;
}
After I try to run this code received these messages
Warnning:
food_language_id column references a foreign key but it is not part of an index. This may trigger full table scans whenever parent table is modified so you are highly advised to create an index that covers this column.
Error:
Ingredient has a foreign key (food_id) that references Food (id) but Food does not have a unique index on those columns nor the columns are its primary key. SQLite requires having a unique constraint on referenced parent columns so you must add a unique index to Food that has (id) column(s).
Could someone help me with that?
Thanks in advance :)
Is it possible to use one of the attributes of a composite primary key as a foreign key? Yes, this is quite common and perfectly valid. The best example comes from the classic many-to-many relationship.
In a foreign key reference, a link is created between two tables when the column or columns that hold the primary key value for one table are referenced by the column or columns in another table. This column becomes a foreign key in the second table. For example, the Sales.
From Books Online: A FOREIGN KEY constraint does not have to be linked only to a PRIMARY KEY constraint in another table; it can also be defined to reference the columns of a UNIQUE constraint in another table. So in your case if you make AnotherID unique, it will be allowed.
A composite key specifies multiple columns for a primary-key or foreign-key constraint. The next example creates two tables. The first table has a composite key that acts as a primary key, and the second table has a composite key that acts as a foreign key.
Ok, I found where was my mistake. My @ForeignKey was wrong, the right one is this:
@ForeignKey(
entity = Food.class,
parentColumns = {"id", "language_id"},
childColumns = {"food_id", "food_language_id"},
onUpdate = CASCADE, onDelete = CASCADE)
The difference is that I put multiple columns inside 'parentColumns' and 'childColumns' and it works correct.
@Danail Alexiev The insertion is something like this:
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertFoods(List<Food> foods);
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertIngredients(List<Ingredient> ingredients);
@Transaction
public void insertFoodData(List<Food> foods, RulesOfGolfDatabase database) {
if (foods != null && database != null) {
insertFoods(foods);
for (Food food : foods) {
insertIngredients(food.getIngrediants());
}
}
}
The most important thing here is that you have to insert first the owner of the @Relation (In this example is Food) and after that every data which is in the relationship
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With