Skip to Main Content

Java APIs

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Converting reflection based class to Generic Class - Need Help!

843793Oct 10 2008 — edited Apr 16 2009
Hi all.

I was under quite a lot of pressure a few weeks ago to deliver a tech demo of a project I was working on; I'm using the JPA for Database comms and I needed to find a VERY quick way to do some basic Insert - Update - Delete operations on the Database. So I came up with the the following example method using Reflection to insert records into the Database. I KNOW its NOT good practise since Reflection is comparatively slow - and I since HAVE changed my project to use Standard JPA Entity Access methods.

My question is this:

I thought it would be really cool if I could write a Generic class that can Communicate with ANY of my Entity Objects without having to know the particulars of the methods and datatypes of the fields inside the Entity. So firstly - is it possible to convert the code below to act in a similar way using Generics? And secondly - would anybody advise against it? And thirdly - If it is possible - could anybody please point me in the right direction on how exactly to go about doing it?

Oh - and I'm NOT an expert on Generics AT ALL - but I would like to attempt to implement a Generic method as described above...

And please - I know my code isn't perfect - this was written in an intense hurry... So please bear with any inadequacies...

The Reflection code:
    /**
     * Temporary helper class - find a better way to do this in the future.
     * This is a reflective method which will persist data from a hashmap
     * to an Entity Class and commit the changes to the underlying Database.
     * The String keys in the HashMap MUST map to the Methods
     * in the persistence Entity, and the values will be persisted by the Entity method
     * identified by the HashMap key.
     * <BR>
     * @param table The name of the Database Entity Class to persist to.
     * @param map The HashMap containing the Method keys and their corresponding values
     * @return Object - The Persistence Entity Object if persistence succeeded, Null if not. If Null is returned,
     * check the Log for further details.
     */
    public Object persist(String table, java.util.HashMap<String, Object> map) {
        Object instance = null;
        Object value = null;
        Object ret = null;
        javax.persistence.EntityManager OrderManagementPersistenceUnitEntityManager = java.beans.Beans.isDesignTime() ? null : javax.persistence.Persistence.createEntityManagerFactory("OrderManagementPersistenceUnit").createEntityManager();
        //Attempt to commit the new record:
        javax.persistence.EntityTransaction tx = OrderManagementPersistenceUnitEntityManager.getTransaction();
        tx.begin();
        try {
	    //Get Entity Class & instance
            Class c = Class.forName(table);
            instance = c.getConstructor((Class[]) null).newInstance((Object[])null);
	    //Get Methods in Entity Class
            java.lang.reflect.Method[] m = c.getDeclaredMethods();
	    //Loop over methods and find the methods that match the HashMap Key
            for(int x = 0; x < m.length; x++) {
                if(map.containsKey(m[x].getName())) {
                    System.out.println("Method operation: " + m[x].getName());
		    //Set value variable to the value identified by the HashMap Key
                    value = map.get(m[x].getName());
                    Class[] paramTypes = m[x].getParameterTypes();
                    if((paramTypes != null) && (paramTypes.length > 0)) {
                        System.out.println(c.getName() + ": Calling method code -> " + m[x].getName() + "(new " + paramTypes[0].getName() + "(\"" + value.toString() + "\"));");
                        if(!paramTypes[0].isPrimitive()) {
			    //Need to use Class.cast for non-primitive data-types
			    //Invoke method in Entity Object.
                            m[x].invoke(instance,paramTypes[0].cast(value));
                        } else {
			    //Invoke method in Entity Object.
                            m[x].invoke(instance,value);
                        }
                    } else {
			//Invoke method in Entity Object.
                        m[x].invoke(instance,value);
                    }
                    if((paramTypes != null) && (paramTypes.length > 0)) {
                        System.out.println(c.getName() + ": Called -> " + m[x].getName() + "(new " + paramTypes[0].getName() + "(\"" + value.toString() + "\")); -> SUCCESS!");
                    }
                }
            }
	    //Commit Entity Object changes...
            OrderManagementPersistenceUnitEntityManager.merge(instance);
            OrderManagementPersistenceUnitEntityManager.flush(); //Only called due to some UI problems -> it works now.
            tx.commit();
            ret = instance;
	//Rollback and log failed transactions.
        } catch (SecurityException ex) {
            Logger.getLogger(persistToDatabase.class.getName()).log(Level.SEVERE, null, ex);     
            ret = null;
            tx.rollback();
        } catch (IllegalAccessException ex) {
            Logger.getLogger(persistToDatabase.class.getName()).log(Level.SEVERE, null, ex);
            ret = null;
            tx.rollback();
            
        } catch (IllegalArgumentException ex) {
            Logger.getLogger(persistToDatabase.class.getName()).log(Level.SEVERE, null, ex);
            ret = null;
            tx.rollback();
            
        } catch (InvocationTargetException ex) {
            Logger.getLogger(persistToDatabase.class.getName()).log(Level.SEVERE, null, ex);
            ret = null;
            tx.rollback();
            
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(persistToDatabase.class.getName()).log(Level.SEVERE, null, ex);
            ret = null;
            tx.rollback();
            
        } catch(Exception ex) {
            Logger.getLogger(persistToDatabase.class.getName()).log(Level.SEVERE, null, ex);
            ret = null;
            tx.rollback();
        } finally {
            OrderManagementPersistenceUnitEntityManager.close();
            return ret;
        }
    }
Any help would be greatly appreciated...
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on May 14 2009
Added on Oct 10 2008
5 comments
744 views