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

3.2k Views Asked by At

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?

2

There are 2 best solutions below

0
On BEST ANSWER

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); 
0
On

Right now I get an SQL Exception, if I add an already created element to the collection, because of the dao.create() in the add() of the collection realization. But for a quite some time we got a dao.createOrUpdate() method, which is better for this situation because it would do an update or simply nothing if we have an already created entity in collection. Is it possible to change this in the source code?

By the way there is an already done and closed ticket (#31) with changes that should automatically set the parent field value on the collection element. But even in the 4.45 I still have to do this manually. Did I miss something or probably do something wrong?