mercredi 17 avril 2019

Ho to invoke Method at runtime without reflection when you don not know class at runtime

My issue is very simple, that can we invoke methods of a class at run time without using reflection specifically at run time in situation like where we have to load tons of data from data base using ORM but in Object Oriented form instead of raw ResultSet.

Now ORM used by my organization is proprietary and what I have seen inside its code that to load data into POJO from data base it uses reflection to set values of fields by invoking getters & setters methods like below code snippet(This is typical solution and most of the ORM follow same)

// somewhere inside my ORM
Object obj = pojo.newInstance();// pojo a Class instance wrapping up original POJO mapping of Table in db

Class type =pojo.getMethod("get"+StringUtils.capitalize(fieldName),Class[0]).getReturnType();

Method m = pojo.getMethod("set"+StringUtils.capitalize(fieldName), new Class[] { paramType });

m.invoke(obj, new Object[] { value });

now here the major issue is with getMethod of class Class, if we check implementation of it inside rt.jar then somewhere we find below code inside Class.class (in rt.jar)

  private static Method searchMethods(Method[] methods,
                                        String name,
                                        Class<?>[] parameterTypes)
    {
        Method res = null;
        String internedName = name.intern();
        for (int i = 0; i < methods.length; i++) {
            Method m = methods[i];
            if (m.getName() == internedName
                && arrayContentsEq(parameterTypes, m.getParameterTypes())
                && (res == null
                    || res.getReturnType().isAssignableFrom(m.getReturnType())))
                res = m;
        }

        return (res == null ? res : getReflectionFactory().copyMethod(res));
    }

this searchMethods is there which is being called by getMethod internally to find method of object.

This is an performance burden because if we have 80 fields in pojo then we have almost 80 getters and 80 setters and in worst case scenario it has to iterate method array for comparison 160 times(80 for getters and 80 for setters)

now if i have to select 6 fields then it has to scan the method array 12 times for getters & setters and if I do select 20 fields then also and so on.

now how to solve this performance issue while maintaining 3 key points
 1. Performance (in terms of iterations)
 2. Less memory usage 
 3. Re-usability

In JPA we have to create different DTOs as per requirement like if we have 6 fields requirement at one side of view then we have to create constructor having 6 fields as parameters and if we need 20 we have to create either new constructor having 20 fields in same DTO or we have to create entire new DTO with those 20 fields while in above approach no constructor needed , new class not required and by method invocation POJO is being utilized everywhere start from dynamic filed selection to update specific fields.

Now I don't want to create multiple DTO or multiple constructors inside POJO instead I want to invoke getter & setters with out reducing performance of my initialization of object via reflection.

So is there another way by which we can invoke on the fly getter and setter methods of POJO without reflection at runtime specially in use case of ORM API? By This I must be keep using my existing ORM rather than switching to Hibernate+JPA





Aucun commentaire:

Enregistrer un commentaire