'Android: how to insert data in manyToMany relationship in Room (Java)

Guys I'm trying to create a database with a manyToMany relationship, I'm able to create the 2 tables of elements but I'm not able to populate the joining table. I don't know how should I insert datas.

This is Card.class:

@Entity
public class Card {

@PrimaryKey(autoGenerate = true)
private Long idCard;

@ColumnInfo(name = "title")
private String title;

@ColumnInfo(name = "taboo_word_1")
private String tabooWord1;

@ColumnInfo(name = "taboo_word_2")
private String tabooWord2;

@ColumnInfo(name = "taboo_word_3")
private String tabooWord3;

@ColumnInfo(name = "taboo_word_4")
private String tabooWord4;

@ColumnInfo(name = "taboo_word_5")
private String tabooWord5;

public Long getIdCard() {
    return idCard;
}

public void setIdCard(Long idCard) {
    this.idCard = idCard;
}

public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}

public String getTabooWord1() {
    return tabooWord1;
}

public void setTabooWord1(String tabooWord1) {
    this.tabooWord1 = tabooWord1;
}

public String getTabooWord2() {
    return tabooWord2;
}

public void setTabooWord2(String tabooWord2) {
    this.tabooWord2 = tabooWord2;
}

public String getTabooWord3() {
    return tabooWord3;
}

public void setTabooWord3(String tabooWord3) {
    this.tabooWord3 = tabooWord3;
}

public String getTabooWord4() {
    return tabooWord4;
}

public void setTabooWord4(String tabooWord4) {
    this.tabooWord4 = tabooWord4;
}

public String getTabooWord5() {
    return tabooWord5;
}

public void setTabooWord5(String tabooWord5) {
    this.tabooWord5 = tabooWord5;
}


}

Tag:

@Entity
public class Tag {

@PrimaryKey(autoGenerate = true)
private long idTag;

@ColumnInfo(name = "tag")
private String tag;

public Tag(String tag) {
    this.tag = tag;
}

public long getIdTag() {
    return idTag;
}

public void setIdTag(long idTag) {
    this.idTag = idTag;
}

public String getTag() {
    return tag;
}

public void setTag(String tag) {
    this.tag = tag;
}


@Override
public String toString() {
    return getTag();
}
}

This is DatabaseTaboom.class:

@Database(entities = {Card.class, Tag.class, CardTagCrossRef.class},
      version = 1)
public abstract class DatabaseTaboom extends RoomDatabase {

public static final String DATABASE_NAME = "db_taboom-1";

public abstract CardDAO cardDao();

public static DatabaseTaboom db;

// Singleton pattern
public static DatabaseTaboom getDatabase(Context applicationContext) {
    if (db == null) {
        db = Room.databaseBuilder(applicationContext, DatabaseTaboom.class, DATABASE_NAME)
                //.allowMainThreadQueries()
                .build();
    }
    return db;
}
}

This is CardDAO.class:

@Dao
public interface CardDAO {

@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertCard(Card card);

@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertTag(Tag tag);

@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertCardWithTags(CardTagCrossRef cardTagCrossRef);

// If called on an item not present in the DB it won't do anything
@Update
public void updateCard(Card card);

@Delete
public void deleteCard(Card card);

// With a query method you can also perform complex inserts/updates/deletes
// Transaction needed for relational classes
@Transaction
@Query("SELECT * FROM Card")
LiveData<List<CardWithTags>> getAllCards();
}

This is CardTagCrossRef.class:

@Entity(primaryKeys = {"idCard", "idTag"})
public class CardTagCrossRef {

public long idCard;
public long idTag;
}

CardWithTags:

public class CardWithTags {

@Embedded private Card card;
@Relation(
        parentColumn = "idCard",
        entityColumn = "idTag",
        associateBy = @Junction(CardTagCrossRef.class)
)

private List<Tag> tagList;

public CardWithTags() {

}

public CardWithTags(Card card, List<Tag> tagList) {
    this.card = card;
    this.tagList = tagList;
}

public Card getCard() {
    return card;
}

public void setCard(Card card) {
    this.card = card;
}

public List<Tag> getTagList() {
    return tagList;
}

public void setTagList(List<Tag> tagList) {
    this.tagList = tagList;
}

@Override
public String toString() {

    String s = getCard().toString();
    s += ", TAG[";
    for (Tag t: getTagList()) {
        s += t + "";
    }
    s+="]";

    return s;
}
}

And this is the method that I wrote to insert a card:

public void insertCard(CardWithTags card) {

    Log.d(TAG, ">>insertCard(): " + card);
    executor.execute(() -> {

        cardDAO.insertCard(card.getCard());
        for (Tag t: card.getTagList()) {
            cardDAO.insertTag(t);
            CardTagCrossRef cardTagCrossRef = new CardTagCrossRef();
            cardTagCrossRef.idCard = card.getCard().getIdCard();
            cardTagCrossRef.idTag = t.getIdTag();
            Log.d(TAG, "CardCrossRef:" + cardTagCrossRef.idCard + cardTagCrossRef.idTag);
            cardDAO.insertCardWithTags(cardTagCrossRef);
        }

        // Check if tags already exists
        cardListIsUpdatedWithDb = false;
    });

}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source