Realm-java: Realm isn't set value to the fields of the objects on reflection

Created on 30 Sep 2018  路  4Comments  路  Source: realm/realm-java

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?

O-Community T-Help

All 4 comments

Realm does not store the values directly in the classes, but instead in native code. This is what powers our lazy-loading mechanism.

This also means that you cannot use reflection to access data in managed Realm objects.

If you truly want to use reflection instead of e.g our DynamicRealm you can use Realm.copyFromRealm(), this will create pure unmanaged Java objects that can be accessed using reflection. This is e.g. what you need to do if you are using GSON, which also uses reflection: https://gist.github.com/cmelchior/ddac8efd018123a1e53a#gistcomment-1861653

But technically if you call setters via reflection then that also works.

But technically if you call setters via reflection then that also works.

Yeah, but don't do that 馃槈

@Zhuinden & @cmelchior
thank you so much ...this is really nice ideas and really nice team
yesterday i tested Zhuinden's solution and it worked like the charm
today I will try to test cmelchior's solution "although I'm a lazy developer but I will take a look "
wish you all the best guys

Was this page helpful?
0 / 5 - 0 ratings