Link to home
Start Free TrialLog in
Avatar of cofactor
cofactor

asked on

copyProperty of BeanUtil class

I see the BeanUtil copyProperty  documentation here..
http://commons.apache.org/beanutils/api/org/apache/commons/beanutils/BeanUtils.html#copyProperty%28java.lang.Object,%20java.lang.String,%20java.lang.Object%29

 I'm unable to set Boolean object using BeanUtils  copyProperty.

Here is my code:
// myType is  a Boolean field
BeanUtils.copyProperty(myVo,"myVo.myInfo.myType", new Boolean(true)); 

Open in new window


// This does not create myInfo instance even !   it shows myInfo=null

How do I  set Boolean(true) using copyProperty then ?

Whats the workaround for this ?
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

Are you completely sure that it's a bean you've got?
ASKER CERTIFIED SOLUTION
Avatar of for_yan
for_yan
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of cofactor
cofactor

ASKER

>>Are you completely sure that it's a bean you've got?

Yes.  

Is that working in your system ?   If yes, please post the sample so that I can test it in my system here.
Can you attach the source for your bean please?
>>>Can you attach the source for your bean please?

Well, here is the code. I am posting the relevant piece of code that you may be interested in.
code.txt
comments please.
It's the full code of FinanceInfoVO and ProposalVO that i need to see

I am wondering, do you understand what this method copyProperty() is supposed to do?

I have a good example which I downoloaded from here:

http://www.avajava.com/tutorials/lessons/how-do-i-copy-properties-from-one-bean-to-another.html?page=1

and nicely tested, which shows how properties of one bean can be copied to properties of another bean
using copyProperties(fromBean, toBean) method (just previos one in the API)
This one really works exactly as expected copying those properties which exist in destination and ignoring
those properties which do not exist in the destination bean.

Now looking at this copyProperty() API description and browsing on the internet
(where this method is obviously much less popular)
I'm trying to understand what it is supposed to do?

Ok, it takes destination bean as parameter,
but from where is it  supposed to copy the property?
And if it copies the property, why you need to provide the value?
And then maybe it should be called setProperty in this case?
And it does not work in this way as a setter - I tried it both with existing or non-existent property and it had no effect in this way.

So I cannot understand it.
I see you are working a lot with beans.
Perhaps you can explain to me, what it is that I'm missing.




Not sure what the problem is - the following worked fine for me right away ...
import org.apache.commons.beanutils.BeanUtils;

public class Beans {
    public static void main(String[] args) throws Exception {
        B1 b1 = new B1();
        b1.setX(true);

        B2 b2 = new B2();
        BeanUtils.copyProperty(b2, "y", b1.getX());
        System.out.println(b2);
    }
}

==========================================================
public class B1 {
    private boolean x;

    public boolean getX() {
        return this.x;
    }

    public void setX(boolean x) {
        this.x = x;
    }
}

==========================================================

public class B2 {
    private Boolean y;

    public Boolean getY() {
        return this.y;
    }

    public void setY(Boolean y) {
        this.y = y;
    }

    public String toString() {
        return String.format("The value of y is %b", y);
    }
}

Open in new window


And it works for me either (see below)
and this copyProperty - why is this copy?
It is just should be setting the property.

But if toBean does not have this which is named
in the method  it will do no change in the toBean,
not even for simple property
package test;

import java.lang.reflect.InvocationTargetException;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.lang.builder.ToStringBuilder;

public class BeanUtilsCopyPropertiesTest {

	public static void main(String[] args) {

		FromBean fromBean = new FromBean("fromBean", "fromBeanAProp", "fromBeanBProp");
		ToBean toBean = new ToBean("toBean", "toBeanBProp", "toBeanCProp");
		System.out.println(ToStringBuilder.reflectionToString(fromBean));
		System.out.println(ToStringBuilder.reflectionToString(toBean));
		try {
			System.out.println("Copying properties to toBean");
			//BeanUtils.copyProperties(toBean, fromBean);
                         //  BeanUtils.copyProperty(toBean,"MyProperty","tratata");
          //  BeanUtilsBean bub = new BeanUtilsBean();
                            BeanUtils.copyProperty(toBean,"CProp","tratata");

		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		System.out.println(ToStringBuilder.reflectionToString(fromBean));
		System.out.println(ToStringBuilder.reflectionToString(toBean));
	}
}

Open in new window



output:

test.FromBean@a62fc3[name=fromBean,aProp=fromBeanAProp,bProp=fromBeanBProp]
test.ToBean@60aeb0[name=toBean,bProp=toBeanBProp,cProp=toBeanCProp]
Copying properties to toBean
test.FromBean@a62fc3[name=fromBean,aProp=fromBeanAProp,bProp=fromBeanBProp]
test.ToBean@60aeb0[name=toBean,bProp=toBeanBProp,cProp=tratata]

Open in new window


package test;

import java.io.Serializable;

public class FromBean implements Serializable {

	private static final long serialVersionUID = 1L;
	private String name;
	private String aProp;
	private String bProp;

	public FromBean() {
	}

	public FromBean(String name, String aProp, String bProp) {
		this.name = name;
		this.aProp = aProp;
		this.bProp = bProp;
	}

	public String getAProp() {
		return aProp;
	}

	public void setAProp(String prop) {
		aProp = prop;
	}

	public String getBProp() {
		return bProp;
	}

	public void setBProp(String prop) {
		bProp = prop;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

Open in new window


package test;

import java.io.Serializable;

public class ToBean implements Serializable {

	private static final long serialVersionUID = 1L;
	private String name;
	private String bProp;
	private String cProp;

	public ToBean() {
	}

	public ToBean(String name, String bProp, String cProp) {
		this.name = name;
		this.bProp = bProp;
		this.cProp = cProp;
	}

	public String getBProp() {
		return bProp;
	}

	public void setBProp(String prop) {
		bProp = prop;
	}

	public String getCProp() {
		return cProp;
	}

	public void setCProp(String prop) {
		cProp = prop;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

Open in new window




So if in the above example you change "CProp" to something which
is not prenset in toBean - then ther will be no change
   BeanUtils.copyProperty(toBean,"CProp","tratata");
in copliance with what API says:

"If the specified bean does not have a property of the specified name, or the property is read only on the destination bean, return without doing anything. "

So it would  not create anything - only would set the specified value
if property exists
Well that seems entirely reasonable
But is it reasonable to call iot copy?
Copy from where?
>>>the following worked fine for me right away

you are not using nested beans !  your code is different .


I'm attaching my project here. I have exported Eclipse java project  src folder.  Please try running  main class  Test.java.  

This is not copying  property.






src.zip
Did you try to use upper case?

In my case when I was trying to  do like that:
  BeanUtils.copyProperty(toBean,"cProp","tratata");
it didn't work

I needed to do like that:

BeanUtils.copyProperty(toBean,"CProp","tratata");

because the methods there in the bena are setCProp, not setcProp

I think the same thing with your property name, try upper case

 BeanUtils.copyProperty(proposalVo, "proposalVo.FinanceInfo.IsFunded", true);

You can't copy/set the property of your member 'financeInfo' of type FinanceInfoVO because no instance of it exists. You need to create it first
>>>Did you try to use upper case?
Yes.  But  that too does not work.


SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
NO, you need to instantiate, sure,  and change to upper case - both things need to be done
why do you need this copy when it is such a pain?
why not just set this property without problems?
It anyways does not copy of anywere - just set it without any BeanUtils.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
You want both of them as string in the second argument

This is not setting nested property - it is setting simple property and we already know that it works for  simple property.

              BeanUtils.copyProperty(proposalVo.getFinanceInfo(), "isFunded", true);

That's not true. Besides, the following works just as well:

"name - Property name (can be nested/indexed/mapped/combo)"
BeanUtils.copyProperty(proposalVo, "financeInfo.isFunded", true);

Open in new window


I also read that:
"name - Property name (can be nested/indexed/mapped/combo)"

but the following

BeanUtils.copyProperty(proposalVo, "financeInfo.isFunded", true);

Open in new window


is how cofactor had it in the very beginning.

Didn't work for him.

After huge pain it did work for me.
I think ther was some mixup with VO and not VO
When I first renamed it all FinanceInfo it worked forst time - then I returned back
and it works like below.

and also in your Test.java you should definitely not have proprsalVO within the quotes:

  BeanUtils.copyProperty(proposalVo, "proposalVo.financeInfo.isFunded", true);

About upper case -lower case - I'm not sure I understadn - in my previous example with copyProperties
I'm sure it required the case as in methods, here it dioes not seem to do it.

Anyway this code exactly works for me
(I removed BaseVO in the process - don't think it makes any difference).
I'd prefer to do normal setting than have all this pain.
Unless you have some special situation, when this method is neccssary.

Anywy there is simpilar method setProprty(...) with similar arguments - do you know what  is the difference?

package com;

import org.apache.commons.beanutils.BeanUtils;




public class Test {
	 public static void main(String[] args) throws Exception {
	        try{

	        ProposalVO proposalVo = new ProposalVO();


	      BeanUtils.copyProperty(proposalVo, "financeInfo.isFunded", true);

	        System.out.println("proposalVo="+proposalVo);
	        System.out.println("proposalVo.getFinanceInfo().isFunded="+proposalVo.getFinanceInfo().getIsFunded());

	        }catch(Exception e){
	        	System.out.println(e);
	        }
	    }
}

Open in new window


package com;


public class FinanceInfoVO {

	private boolean isFunded;

   public FinanceInfoVO(){
        isFunded =  false;
    }

	public void setIsFunded(boolean b) {
		this.isFunded = b;
	}

	public boolean getIsFunded() {
		return isFunded;
	}

}

Open in new window


package com;

public class ProposalVO  {
	private FinanceInfoVO financeInfo;
public ProposalVO(){
    financeInfo = new FinanceInfoVO();
}

	public void setFinanceInfo(FinanceInfoVO f) {
		this.financeInfo = f;
	}

	public FinanceInfoVO getFinanceInfo() {
		return financeInfo;
	}


}

Open in new window


proposalVo=com.ProposalVO@12d03f9
proposalVo.getFinanceInfo().isFunded=true

Open in new window



SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>>>and also in your Test.java you should definitely not have proprsalVO within the quotes:

strange !  ..I do that  way to copyProperties for String property and they work fine. ..so tried the same to copy boolean property .

Is this  only for  Boolean property that I can not keep proprsalVO within the quotes ?

By the way , I'm no longer using this code now, I have switched to  <s:hidden of Struts 2 which loads the data as expected and solved my problem.

But would still like to know what caused the problem?


This is with proposalVo:
package com;

import org.apache.commons.beanutils.BeanUtils;




public class Test {
	 public static void main(String[] args) throws Exception {
	        try{

	        ProposalVO proposalVo = new ProposalVO();


	      BeanUtils.copyProperty(proposalVo, "proposalVo.financeInfo.isFunded", true);

	        System.out.println("proposalVo="+proposalVo);
	        System.out.println("proposalVo.getFinanceInfo().isFunded="+proposalVo.getFinanceInfo().getIsFunded());

	        }catch(Exception e){
	        	System.out.println(e);
	        }
	    }
}

Open in new window


Output:
proposalVo=com.ProposalVO@1ac3c08
proposalVo.getFinanceInfo().isFunded=false

Open in new window


This is with only cahnge - removal of proprosalVo:



package com;

import org.apache.commons.beanutils.BeanUtils;




public class Test {
	 public static void main(String[] args) throws Exception {
	        try{

	        ProposalVO proposalVo = new ProposalVO();


	      BeanUtils.copyProperty(proposalVo, "financeInfo.isFunded", true);

	        System.out.println("proposalVo="+proposalVo);
	        System.out.println("proposalVo.getFinanceInfo().isFunded="+proposalVo.getFinanceInfo().getIsFunded());

	        }catch(Exception e){
	        	System.out.println(e);
	        }
	    }
}

Open in new window



Output:

proposalVo=com.ProposalVO@15dfd77
proposalVo.getFinanceInfo().isFunded=true

Open in new window

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial