Solved

how to prevent losing values that already exists in source bean in case of BeanUtils

Posted on 2011-09-21
19
616 Views
Last Modified: 2012-05-12
           dept.setId("123");
            emp.setName("john");
            
            try {
                   BeanUtils.copyProperties(emp,dept);
                   System.out.println(emp.getName());
                   } catch (Exception e) {
                  
            }


            dept is the source bean and emp is the destintion bean.

            whatever values exists in Department bean should be copied into Employee bean.

            problem is if values already exists in Employee bean(for example value already existed in Name of employee bean)
            should not lose if values doesn't exist in Department bean.How to prevent this?
0
Comment
Question by:chaitu chaitu
  • 9
  • 7
  • 3
19 Comments
 
LVL 4

Expert Comment

by:reijnemans
ID: 36578639
Hi best thing to dois write your own copier. So you have full control over what values are copied. besides that youre own copied should be faster, because BeanUtils.copy works with reflection, you own bean doesn't
0
 
LVL 40

Expert Comment

by:gurvinder372
ID: 36578645
why don't you override the copyProperties method of BeanUtils after extending the same
0
 
LVL 40

Accepted Solution

by:
gurvinder372 earned 250 total points
ID: 36578650
0
 
LVL 4

Expert Comment

by:reijnemans
ID: 36578666
I cannot see the link gurvinder posted, so maybe I tell the same.

you could also change you're implementation of your setters into this:

public void setName(String name) {
     if (name == null) {
          name = name;
     }
}

Open in new window


if it also should be possible that you could change the value of name, you could create a second setter
0
 
LVL 20

Author Comment

by:chaitu chaitu
ID: 36578676
my question title little bit wrong .Destination bean values should not lose if already exists.
0
 
LVL 40

Expert Comment

by:gurvinder372
ID: 36578684
Thats why either you should write your own copier or override beanutils copy properties method
0
 
LVL 20

Author Comment

by:chaitu chaitu
ID: 36579750
Spring's BeanUtils is working as per my requirement.its behaving quite differently as apache's.

If you see below code Destination Bean value is holding its value even if origin bean value is null while copying properties.
check the below code ..


import org.springframework.beans.BeanUtils;

class  Test
{
	public static void main(String[] args) 
	{
		Department origin= new Department();
		Employee dest= new Employee();
		
		origin.setId("123");
		origin.setName(null);
		
		dest.setName("john");

		
		try {
			 System.out.println(origin.getName()+":before:"+dest.getName());

			 BeanUtils.copyProperties(dest,origin);

			 System.out.println(origin.getName()+":after:"+dest.getName());
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
}



OUTPUT
*******
null:before:john
john:after:john

Open in new window

0
 
LVL 4

Expert Comment

by:reijnemans
ID: 36579883
But what if origin.setName(null) is origin.setName("harry") the result is:

OUTPUT
********
harry:before:john
john:after:john

Open in new window

Is this what you want?
0
 
LVL 20

Author Comment

by:chaitu chaitu
ID: 36579905
hmm.No

Department origin= new Department();
Employee dest= new Employee();
            
origin.setId("123");
origin.setName("John");
            
dest.setName("");
 BeanUtils.copyProperties(dest,origin);

then destination should display as John but ouput is coming as null.then what is the solution??


0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 4

Expert Comment

by:reijnemans
ID: 36579909
writing you're own copy class
0
 
LVL 20

Author Comment

by:chaitu chaitu
ID: 36579942
how to exclude some of the getMethods while copying properties.i didnt understand the link given by gurvinder.

I have seen in spring's BeanUtils some ignorePorperties.i think apache's its not there..
0
 
LVL 4

Expert Comment

by:reijnemans
ID: 36579968
Sorry as I mentioned I cannot see the given solutions of the link of gurvinder.

BeanUtils gives indeed a property ignore fields, but then you have to know which fields you don't want to copy. The best thing you coudl do is write a specified copier, instead of using beanUtils. Writing you're own copier is also faster than bean utils.

0
 
LVL 20

Author Comment

by:chaitu chaitu
ID: 36580225
This is the code given by gurvinder.its working fine.as you can see i have excluded the name property while copying.

I have doubt here ;do i need this code bcos its commented out there.

if (orig instanceof DynaBean) {
					        DynaProperty[] origDescriptors = ((DynaBean) orig).getDynaClass()
					                                                                          .getDynaProperties();
 
					        for (int i = 0; i < origDescriptors.length; i++) {
					                String name = origDescriptors[i].getName();
 
					                if (getPropertyUtils().isWriteable(dest, name)) {
					                        Object value = ((DynaBean) orig).get(name);
					                        copyProperty(dest, name, value);
					                }
					        }
					}


]

Open in new window


public class CustomBeanCopy  {
	public static void main(String[] args)
		throws InvocationTargetException, IllegalAccessException {
		// Override copyProperties
 
		/* StringList is just a utility encapsulating a List of String
		 * The list would be read from a file normally
		 */
		final ArrayList exclusionsList = new ArrayList();
		exclusionsList.add("name"); // Exclude the 'b' field
 
		BeanUtilsBean bub = new BeanUtilsBean() {
				public void copyProperties(Object dest, Object orig)
					throws IllegalAccessException, InvocationTargetException {
					// Validate existence of the specified beans
					if (dest == null) {
						throw new IllegalArgumentException(
							"No destination bean specified");
					}
 
					if (orig == null) {
						throw new IllegalArgumentException(
							"No origin bean specified");
					}
 
					// Copy the properties, converting as necessary
					/*	
					if (orig instanceof DynaBean) {
					        DynaProperty[] origDescriptors = ((DynaBean) orig).getDynaClass()
					                                                                          .getDynaProperties();
 
					        for (int i = 0; i < origDescriptors.length; i++) {
					                String name = origDescriptors[i].getName();
 
					                if (getPropertyUtils().isWriteable(dest, name)) {
					                        Object value = ((DynaBean) orig).get(name);
					                        System.out.println(name+"..48.."+value);
					                        copyProperty(dest, name, value);
					                }
					        }
					} else if (orig instanceof Map) {
					        Iterator names = ((Map) orig).keySet().iterator();
 
					        while (names.hasNext()) {
					                String name = (String) names.next();
 
					                if (getPropertyUtils().isWriteable(dest, name)) {
					                        Object value = ((Map) orig).get(name);
					                        copyProperty(dest, name, value);
					                }
					        }
					} else // if (orig is a standard JavaBean)
					 */
			PropertyDescriptor[] origDescriptors = getPropertyUtils().getPropertyDescriptors(orig);
 
					for (int i = 0; i < origDescriptors.length; i++) {
						String name = origDescriptors[i].getName();
			
						if (exclusionsList.contains(name) ||
								"class".equals(name)) {
							continue; // No point in trying to set an object's class
						}
 
						if (getPropertyUtils().isReadable(orig, name) &&
								getPropertyUtils().isWriteable(dest, name)) {
							try {
								Object value = getPropertyUtils().getSimpleProperty(orig, name);
								copyProperty(dest, name, value);
							} catch (NoSuchMethodException e) {
								; // Should not happen
							}
						}
					}
				}
			};
 
		// Do the copying
		Employee emp = new Employee(); 
		
		emp.setName(null);
		Department dest = new Department();
		dest.setName("john");
		
		bub.copyProperties(dest, emp);
		
		System.out.println("97.."+dest.getName()); // Shows 'name' as having been excluded
		
		
	}
} 

Open in new window

0
 
LVL 4

Assisted Solution

by:reijnemans
reijnemans earned 250 total points
ID: 36580269
Depends, if you only want to exclude the name property you also could use the Spring BeanUtils

BeanUtils.copyProperties(dest, emp, null, bew String[] {"name"});

Open in new window

0
 
LVL 20

Author Comment

by:chaitu chaitu
ID: 36580300
what is the use of this code.i dont think its neccssary.

if (orig instanceof DynaBean) {
					        DynaProperty[] origDescriptors = ((DynaBean) orig).getDynaClass()
					                                                                          .getDynaProperties();
 
					        for (int i = 0; i < origDescriptors.length; i++) {
					                String name = origDescriptors[i].getName();
 
					                if (getPropertyUtils().isWriteable(dest, name)) {
					                        Object value = ((DynaBean) orig).get(name);
					                        copyProperty(dest, name, value);
					                }
					        }
					}

Open in new window

0
 
LVL 4

Expert Comment

by:reijnemans
ID: 36580324
This code is reading the properties of the origin class and then checks whether there is a setter for this propertiy on the destination bean.
0
 
LVL 4

Expert Comment

by:reijnemans
ID: 36580344
But propbably you don't have a DynaBean so it is not necessary. And you could remove the code
0
 
LVL 20

Author Comment

by:chaitu chaitu
ID: 36585102
I think  below Spring BeanUtils.copyProperties method takes only three arguments(BeanUtils.copyProperties(dest, emp, new String[] {"name"});



BeanUtils.copyProperties(dest, emp, null, bew String[] {"name"});
0
 
LVL 4

Expert Comment

by:reijnemans
ID: 36585371
you're right the copyProperties I posted was a private method :-O. So problem solved?
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

For customizing the look of your lightweight component and making it look lucid like it was made of glass. Or: how to make your component more Apple-ish ;) This tip assumes your component to be of rectangular shape and completely opaque. (COD…
Are you developing a Java application and want to create Excel Spreadsheets? You have come to the right place, this article will describe how you can create Excel Spreadsheets from a Java Application. For the purposes of this article, I will be u…
Viewers learn about the third conditional statement “else if” and use it in an example program. Then additional information about conditional statements is provided, covering the topic thoroughly. Viewers learn about the third conditional statement …
Viewers will learn about the different types of variables in Java and how to declare them. Decide the type of variable desired: Put the keyword corresponding to the type of variable in front of the variable name: Use the equal sign to assign a v…

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now