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!