Why can’t isNotNull be executed on columns with DataType.SERIALIZABLE in ormlite?
With ORMLite 4.48 on Android, consider the following user table….
@DatabaseTable(tableName = "users")
public class User {
@DatabaseField(columnName = Column.UUID)
protected String uuid;
@DatabaseField(columnName = Column.FIRST_NAME)
protected String firstName = null;
@DatabaseField(columnName = Column.LAST_NAME)
protected String lastName = null;
@DatabaseField(columnName = Column.ADDRESS, dataType = DataType.SERIALIZABLE)
protected Address address = null;
// ...
}
(Address classes represent human-readable addresses, converted from latitude/longitude).
… Use the following query….
<pre class=”lang-java prettyprint-override”>List<User> users = getDbHelper().getDao(User.class)
.queryBuilder()
.where()
.isNotNull(User.Column.ADDRESS)
.query();
… This exception is thrown:
java.sql.SQLException: Field 'address' is of data type com.j256.ormlite.field.types.SerializableType@42ac7650 which can not be compared
at com.j256.ormlite.stmt.query.BaseComparison.<init>(BaseComparison.java:27)
at com.j256.ormlite.stmt.query.IsNotNull.<init>(IsNotNull.java:19)
at com.j256.ormlite.stmt.Where.isNotNull(Where.java:315)
...
Obviously, the IS NOT NULL
clause cannot be used for fields stored as DataType.SERIALIZABLE.
Digging into the ORMLite code, the BaseComparison constructor checks whether the fieldType is comparable:
protected BaseComparison(String columnName, FieldType fieldType, Object value, boolean isComparison)
throws SQLException {
if (isComparison && fieldType != null && !fieldType.isComparable()) {
throw new SQLException("Field '" + columnName + "' is of data type " + fieldType.getDataPersister()
+ " which can not be compared");
}
...
}
Obviously, SerializableType.isComparable()
returns false
:
@Override
public boolean isComparable() {
return false;
}
So, it’s clear to me why the exception is thrown. But why can’t you do Where.isNull() or Where.isNotNull()
? Is this a limitation of SQLite or did the author of ORMLite make this decision?
Solution
Not sure “why”, but I believe the “how” is to use ForeignCollectionField
instead of DatabaseField