yahoo/squidb

java.lang.UnsupportedOperationException: numbers not found in model. Make sure the value was set explicitly, read from a cursor, or that the model has a default value for this property.

lpellegr opened this issue · 2 comments

I am using Squidb with the JSON plugin.

Below is my use case example:

@TableModelSpec(className = "AlertContact", tableName = "AlertContact", noRowIdAlias = true)
public class AlertContactSpec {

    public long createdAt;

    // ...

    @JSONColumn
    public List<String> numbers;

    @ModelMethod
    public static void addNumber(AlertContact alertContact, String number) {
        List<String> numbers = alertContact.getNumbers();

        if (numbers == null) {
            alertContact.setNumbers(Lists.newArrayList(number));
        } else {
            if (!numbers.contains(number)) {
                numbers.add(number);
                alertContact.setNumbers(numbers);
            }
        }
    }

}

I have recently upgraded to Squidb 3.2.3 from 3.2.2. Since this update, I am getting the following error:

java.lang.UnsupportedOperationException: numbers not found in model. Make sure the value was set explicitly, read from a cursor, or that the model has a default value for this property.

when I try to execute:

Database database = Database.getInstance(mContext);

database.beginTransaction();

try {
    AlertContact alertContact = database.fetchByQuery(
            AlertContact.class,
            Query.select(AlertContact.PROPERTIES)
                    .where(AlertContact.CONTACT_ID.eq(mContactId)));

    if (alertContact == null) {
        alertContact = new AlertContact();
        alertContact.setCreatedAt(System.currentTimeMillis());
        alertContact.setContactId(mContactId);
        alertContact.setName(mDisplayName);
    }

    alertContact.addNumber(mNumber);

    database.persist(alertContact);

    database.setTransactionSuccessful();

    return true;
} catch (Exception e) {
    FirebaseCrash.report(e);
    return false;
} finally {
    database.endTransaction();
}

The exception is thrown when alertContact.addNumber(mNumber); is executed.

A quick debugging lets me think the issue is due to the fact that the field numbers from AlertContactSpec has no default value. However, I have no idea how to set a default value for this JSON field. Is it possible? if yes, what about backward compatibility with schema created without this default value?

https://github.com/yahoo/squidb/blob/master/squidb/src/com/yahoo/squidb/data/AbstractModel.java#L323

@lpellegr yes, this is actually a bug fix in 3.2.3 to make JSONProperties behave the same as other properties when the field is not present in the model. If you want a default value of null to be present in the in-memory values, simply specify it using @ColumnSpec:

@ColumnSpec(defaultValue=ColumnSpec.DEFAULT_NULL)
List<String> numbers;

The SQLite column will default to null anyways, so no migration is necessary, but you need to explicitly specify if you want an in-memory default value for unpersisted models or models that didn't read all properties from the database. This is also consistent with how all other property types behave.

Hope that helps!

@sbosley Thank you for the clear explanations. Problem fixed.