Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Realm isn't set value to the fields of the objects on reflection (Android)

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?

like image 445
Abdulmalek Dery Avatar asked Nov 07 '22 01:11

Abdulmalek Dery


1 Answers

Realm doesn't support setting field values of managed objects via reflection.

It will however work if you call the setter methods through reflection.

like image 125
EpicPandaForce Avatar answered Nov 14 '22 21:11

EpicPandaForce