I created a dummy Entity class:
@Entity
data class Entity(
@PrimaryKey
val id: Long?=null,
val data1: DataClass1? = null,
val data2: DataClass2? = null
)
data class DataClass1(
val text: String = "",
val c: Char = ' '
)
data class DataClass2(
val num1: Float = 0.0f,
val num2: Long = 0,
)
Then I created a Converter class:
@ProvidedTypeConverter
class Converters {
@TypeConverter
fun A_YYYYY(json: String): DataClass2 = Gson().fromJson(json, DataClass2::class.java)
@TypeConverter
fun Z_YYYYY(data: DataClass2): String = Gson().toJson(data)
@TypeConverter
fun A_XXXXX(json: String): DataClass1 = Gson().fromJson(json, DataClass1::class.java)
@TypeConverter
fun Z_XXXXX(data: DataClass1): String = Gson().toJson(data)
}
where I purposely gave the methods nonsense names and changed the order – the converter’s method for the DataClass2 is first and for the DataClass1 is second (the opposite to the order in the Entity class).
So how does Room know how to match the methods in the generated file?
The code in an auto generated file Dao_Impl:
@Override
public Object getEntityById(final long id, final Continuation<? super Entity> arg1) {
final String _sql = "SELECT * FROM entity WHERE id = ?";
final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 1);
int _argIndex = 1;
_statement.bindLong(_argIndex, id);
final CancellationSignal _cancellationSignal = DBUtil.createCancellationSignal();
return CoroutinesRoom.execute(__db, false, _cancellationSignal, new Callable<Entity>() {
@Override
@Nullable
public Entity call() throws Exception {
final Cursor _cursor = DBUtil.query(__db, _statement, false, null);
try {
final int _cursorIndexOfId = CursorUtil.getColumnIndexOrThrow(_cursor, "id");
final int _cursorIndexOfData1 = CursorUtil.getColumnIndexOrThrow(_cursor, "data1");
final int _cursorIndexOfData2 = CursorUtil.getColumnIndexOrThrow(_cursor, "data2");
final Entity _result;
if (_cursor.moveToFirst()) {
final Long _tmpId;
if (_cursor.isNull(_cursorIndexOfId)) {
_tmpId = null;
} else {
_tmpId = _cursor.getLong(_cursorIndexOfId);
}
final DataClass1 _tmpData1;
final String _tmp;
if (_cursor.isNull(_cursorIndexOfData1)) {
_tmp = null;
} else {
_tmp = _cursor.getString(_cursorIndexOfData1);
}
_tmpData1 = __converters().A_XXXXX(_tmp);
final DataClass2 _tmpData2;
final String _tmp_1;
if (_cursor.isNull(_cursorIndexOfData2)) {
_tmp_1 = null;
} else {
_tmp_1 = _cursor.getString(_cursorIndexOfData2);
}
_tmpData2 = __converters().A_YYYYY(_tmp_1);
_result = new Entity(_tmpId,_tmpData1,_tmpData2);
} else {
_result = null;
}
return _result;
} finally {
_cursor.close();
_statement.release();
}
}
}, arg1);
}
private synchronized Converters __converters() {
if (__converters == null) {
__converters = __db.getTypeConverter(Converters.class);
}
return __converters;
}
The specific parts where the converter functions are matched to the data:
final int _cursorIndexOfData1 = CursorUtil.getColumnIndexOrThrow(_cursor, "data1");
final int _cursorIndexOfData2 = CursorUtil.getColumnIndexOrThrow(_cursor, "data2");
//.............................
if (_cursor.isNull(_cursorIndexOfData1)) {
_tmp = null;
} else {
_tmp = _cursor.getString(_cursorIndexOfData1);
}
_tmpData1 = __converters().A_XXXXX(_tmp);
//.............................
if (_cursor.isNull(_cursorIndexOfData2)) {
_tmp_1 = null;
} else {
_tmp_1 = _cursor.getString(_cursorIndexOfData2);
}
_tmpData2 = __converters().A_YYYYY(_tmp_1);
There isn’t any:
__converters().forEach{ it ->
if(_tmp_1.dataType == it.dataType){
//some code
}
}
or something like that. So how does it know that?