*
The moose likes Java in General and the fly likes Fill bean data from HashMap using Reflection Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Fill bean data from HashMap using Reflection" Watch "Fill bean data from HashMap using Reflection" New topic
Author

Fill bean data from HashMap using Reflection

Ravi Sree
Ranch Hand

Joined: Jan 24, 2010
Posts: 62

Hi all,

I was trying on a small example on Reflection by which i had to fill the values in a bean from a HashMap.
This is the code as it goes: -

TempBean.java


ReflectUtil.java


ReflectionTester.java


But on executing ReflectionTester with the arguments, A NullPointerException is getting thrown.
Please suggest where am i going wrong here.

Thanks in advance.
Sree
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19653
    
  18

If pDescriptors[i].getName().equals("class") you will get a "gap" in your descriptors array; the value will remain null at that point. You will later encounter this null value, and when you try to get its name the exception is thrown. Change descriptors from a PropertyDescriptor[] to a List<PropertyDescriptor> to make sure you won't get any null references in it. Note that you'll need to replace descriptors[i] = pDescriptors[i] with descriptors.add(pDescriptors[i]), descriptors.length with descriptors.size() and descriptors[k] with descriptors.get(k).

That leaves another odd issue. You loop over the number of values given, which can definitely be different from the number of properties. Change the for loop:
The final question: what will you do if a property has no entry in the map?


Oh, and your ReflectionUtil class is superfluous. All it does is forward the call to its arguments. ReflectionUtil.getReadMethod(descriptors[k]) is the same as descriptors[k].getReadMethod(), and ReflectionUtil.invokeMethod(method, tempBean2, value) is the same as method.invoke(tempBean2, value). You won't even need to catch the NoSuchMethodException anymore.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Wouter Oet
Saloon Keeper

Joined: Oct 25, 2008
Posts: 2700

There are a couple of things weird about your code:




You're not using generics. And probably your problem is that you are iterating over the HashMap size and not over the
descriptors size. And why do you copy all the values into a new array except for the class entries? Why not just skip them?


"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." --- Martin Fowler
Please correct my English.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38007
    
  22
Reflection is hardly a "beginning" topic. Moving thread.
Ravi Sree
Ranch Hand

Joined: Jan 24, 2010
Posts: 62

Hi again,

Thanks for all your comments.

@Rob Prime-
I followed your suggestions, made the changes in the method. and it gave me what i wanted, Thanks friend

ReflectionTester.java


@Wouter Oet
I will make sure i remove the unnecessary code as you said.
Appreciate your help.

The code after undergoing the changes as Rob had suggested, is working without an error.

>
Wouter Oet
Saloon Keeper

Joined: Oct 25, 2008
Posts: 2700

You could improve your code by merging the two for-loops into one.
Ravi Sree
Ranch Hand

Joined: Jan 24, 2010
Posts: 62

Wouter Oet wrote:There are a couple of things weird about your code:




You're not using generics. And probably your problem is that you are iterating over the HashMap size and not over the
descriptors size. And why do you copy all the values into a new array except for the class entries? Why not just skip them?



Hi,

I think i have removed unnecessary code as suggested earlier.
But I again ran into another problem similiar like this..
These are the classes : -

FormUtil


BaseForm


LoginForm


BeanUtil


Here i am trying the a similiar example to set values from hashmap to the class,
but i am getting a error(IllegalArgugmentException) while invoking the method,
Please suggest what can be the reason and what to do to correct this...

Thanks in advance.

Regards,
Sree
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

The reason? When you called the invoke() method, an error was thrown. Perhaps by the method you were invoking? You don't know because you didn't...

What can be done about it?
Look at the stack trace to see what the error was. Not only will there be a stack trace for the InvocationTargetException, there will also be a stack trace for the actual exception which was thrown by the invoked method.
Ravi Sree
Ranch Hand

Joined: Jan 24, 2010
Posts: 62

Paul Clapham wrote:The reason? When you called the invoke() method, an error was thrown. Perhaps by the method you were invoking? You don't know because you didn't...

What can be done about it?
Look at the stack trace to see what the error was. Not only will there be a stack trace for the InvocationTargetException, there will also be a stack trace for the actual exception which was thrown by the invoked method.


Hi Paul,

Thanks for replying,
I had written InvocationTargetException for IllegalArgumentException by mistake,
the stacktrace shown is follows:-

java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at net.utils.BeanUtil.setFromMap(BeanUtil.java:56)
at net.utils.FormUtil.parseRequest(FormUtil.java:44)


I still cant make out what made it to throw this exception.
Please forgive my typeing-mistake and suggest what should be done to correct this.

Regards,
Sree
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19653
    
  18

Your first argument is a Class object, but it needs to be an instance of the class represented by the Class object. For example, if clazz == String.class you would need to pass a String.
Ravi Sree
Ranch Hand

Joined: Jan 24, 2010
Posts: 62

Rob Prime wrote:
Your first argument is a Class object, but it needs to be an instance of the class represented by the Class object. For example, if clazz == String.class you would need to pass a String.


Hi Rob,

I did the change


Please suggest if this ok as this working right as i needed.

Regards,
Sree
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19653
    
  18

It depends. If it's ok to call the method on a new instance that isn't referred to from anywhere else, then that code should work. If you need to call the method on an existing instance then you'll need to pass that instance to the method. Something tells me that's the case.

I'd change your method signature slightly:
You will now be setting the values to an existing object.
Ravi Sree
Ranch Hand

Joined: Jan 24, 2010
Posts: 62

Rob Prime wrote:It depends. If it's ok to call the method on a new instance that isn't referred to from anywhere else, then that code should work. If you need to call the method on an existing instance then you'll need to pass that instance to the method. Something tells me that's the case.

I'd change your method signature slightly:
You will now be setting the values to an existing object.


I did the changes as you said,
if i pass the argument as object i get the class after getClass() as of type <java.lang.Class>
and not of the type <net.forms.LoginForm>, and i plan to set this instance in request attribute

I get a hint that i will have to use java Generics here, but am not much aquainted with it.

Please guide about what can be done to make method work right.

Sree
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19653
    
  18

You no longer should pass the Class object as your first argument but an instance of that class - the instance whose fields you want to set.
Ravi Sree
Ranch Hand

Joined: Jan 24, 2010
Posts: 62

Rob Prime wrote:You no longer should pass the Class object as your first argument but an instance of that class - the instance whose fields you want to set.


Could you elaborate with a code sample please.

Sree
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19653
    
  18

Ravi Sree
Ranch Hand

Joined: Jan 24, 2010
Posts: 62

Rob Prime wrote:


Hi ,

I tried to improve the code a bit more,
Even though i have a general idea how the
code should work, I am havent yet appplied
this method successfully.
I think using Java Generics will work here,
so i started with these changes, but couldn't
go any further.

BeanUtil


I plan to send the object to the method,
set the values and return the same object
back, where (object extends BaseForm)

I am missing the core concept of Java Generics here,
but want to clear them too.

Please guide me.

Thanks in advance,
Sree">
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19653
    
  18

Why do you create a new Object to pass into writeMethod.invoke? Why not use the argument to the method, as I've shown before?
Ravi Sree
Ranch Hand

Joined: Jan 24, 2010
Posts: 62

Rob Prime wrote:Why do you create a new Object to pass into writeMethod.invoke? Why not use the argument to the method, as I've shown before?

quote=Rob Prime]Why do you create a new Object to pass into writeMethod.invoke? Why not use the argument to the method, as I've shown before?
Hi Rob,
Sorry for replying late.
I followed your suggestion and used it Java Generics
and was able to find the required solution.

Thanks,
Regards,
Sree">
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19653
    
  18

I see two possible improvements:
- use Map<String,String> instead of HashMap<String,String> in the method signature to allow TreeMap as well.
- check if the method's parameter list expects only one String or Object:
This will prevent issues where the property is not a String property but for instance an Integer.
Ravi Sree
Ranch Hand

Joined: Jan 24, 2010
Posts: 62

Rob Prime wrote:I see two possible improvements:
- use Map<String,String> instead of HashMap<String,String> in the method signature to allow TreeMap as well.
- check if the method's parameter list expects only one String or Object:
This will prevent issues where the property is not a String property but for instance an Integer.


Hi Rob,

Sorry to reply so late,

I have the made changes to my code as you suggested.

Thanks ,
Sree
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Fill bean data from HashMap using Reflection
 
Similar Threads
Call alot of setters from another class
Unknown error with JDBC code or with driver.
merging data values of two similar objects
DnD with JLabel subclass
what is introspection?