Search code examples
androidormliteforeign-collection

ORMLite and adding an existing persisted entity to a foreign field collection


I have a Language entity with a ForeignCollection of Country entities:

@ForeignCollectionField(eager = false, foreignFieldName = "language")
public ForeignCollection<Country> countries;

I create a country, say representing France, in my database. Later, I retrieve it by querying for its id and I want to add this to a Language's foreign collection of countries:

Country country = dbHelper.getCountryDao().queryForId(countryId);
if (country != null) {
    country.language = language;    
    ForeignCollection<Country> countries = language.countries;
    if (countries == null) {
        countries = dbHelper.getLanguageDao().getEmptyForeignCollection("countries");
    }
    countries.add(country); // Illegal state exception thrown here
    language.countries = countries;
    dbHelper.getLanguageDao().create(language);
}

However, the marked line countries.add(country) causes an illegal state exception to be thrown:

01-27 13:39:19.112: E/AndroidRuntime(15614): Caused by: java.sql.SQLException: inserting to database failed: INSERT INTO countries (identifier ,name ,language_id ) VALUES (?,?,?) 01-27 13:39:19.112: E/AndroidRuntime(15614): at com.j256.ormlite.misc.SqlExceptionUtil.create(SqlExceptionUtil.java:22)

Why does .add() trigger the recreation of an entity existing in the database and the internal DAO? And what should I be doing instead?


Solution

  • Why does .add() trigger the recreation of an entity existing in the database and the internal DAO?

    It does this because that is how it was designed. To quote the javadocs for EagerForeignCollection#add():

    Add an element to the collection. This will also add the item to the associated database table.

    The country already exists in the table so an exception is thrown. You can associate an existing country with a language by doing something like the following:

    country.language = language;
    dbHelper.getCountryDao().update(country);
    

    Then if you want to refresh your eager collection in the language you do:

    dbHelper.getLanguageDao().refresh(language);