I'm trying to implement an abstraction to realm so that I could save some time when using the CURD operation on the db.
the abstraction that I build is controller
to the database operation so that I could use this controller
which do the CURD operation with any table.
i.e. the controller
I'm talking about is just a Java class
has four methods
create
update
read
delete
.
this is the create
which using reflection to create the db objects
and bind the fields of the passed data object
to that db object
/**
* this method will delete the old data "you can change that"
* of the table then store the passed data array in the table
*
* @param datum the data Object you want to
* save in the database
* @param map this map will contain which field
* value in the data class will be
* binded to which field in the db class
* and will have this form dataFieldName => dbFieldName
* @param callback when the function finish it's work it will
* return a boolean value indicate whether
* the function successfully finish it's work
*/
public void create(
Object datum,
Class dataClass,
HashMap<String, String> map,
SaveDataCallback callback
) {
Realm realm = Realm.getInstance(configuration);
realm.executeTransactionAsync(bgRealm -> {
long id;
Number currentId = bgRealm.where(clacc).max("id");//the clacc object is passed in the constructor of the controller
if (currentId == null)
id = 1;
else
id = currentId.longValue() + 1;
RealmObject dbObject = bgRealm.createObject(clacc, id++);//the clacc object is passed in the constructor of the controller
mapObjects(datum, dataClass, dbObject, clacc, map);
}
, () -> callback.onSavingDataFinished(true)
, error -> callback.onSavingDataFinished(false));
}
private void mapObjects(
Object source,
Class sourceClass,
Object destination,
Class destinationClass,
HashMap<String, String> map) {
String[] sourceFieldNames = map.keySet().toArray(new String[map.size()]);
try {
for (int i = 0; i < map.size(); i++) {
Field sourceField = sourceClass.getDeclaredField(sourceFieldNames[i]);
sourceField.setAccessible(true);
Object sourceValue = sourceField.get(source);
String destinationFieldName = map.get(sourceFieldNames[i]);
Field destinationField = destinationClass.getDeclaredField(destinationFieldName);
destinationField.setAccessible(true);
if (sourceField.getType() == Short.TYPE) {
destinationField.set(destination, Short.parseShort(sourceValue.toString()));
continue;
}
if (sourceField.getType() == Integer.TYPE) {
destinationField.set(destination, Integer.parseInt(sourceValue.toString()));
continue;
}
if (sourceField.getType() == Long.TYPE) {
destinationField.set(destination, Long.parseLong(sourceValue.toString()));
continue;
}
if (sourceField.getType() == Float.TYPE) {
destinationField.set(destination, Float.parseFloat(sourceValue.toString()));
continue;
}
if (sourceField.getType() == Double.TYPE) {
destinationField.set(destination, Double.parseDouble(sourceValue.toString()));
continue;
}
if (sourceField.getType() == Byte.TYPE) {
destinationField.set(destination, Byte.parseByte(sourceValue.toString()));
continue;
}
if (sourceField.getType() == Boolean.TYPE) {
destinationField.set(destination, Boolean.parseBoolean(sourceValue.toString()));
continue;
}
destinationField.set(destination, sourceValue);
}
} catch (Exception e) {
e.printStackTrace();
}
}
the problem is as follow:
when I'm trying to query the database to get the object after the finish of the process the database return the objects that I create using this function but those objects has no data actually the returned data is set to default value to each type i.e. string to null boolean to false etc...
my question is:
is there any problem in my code or the realm database doesn't support setting values to the objects on reflection?
Realm doesn't support setting field values of managed objects via reflection.
It will however work if you call the setter methods through reflection.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With