Solved

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

Posted on 2011-09-21
19
623 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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

For customizing the look of your lightweight component and making it look opaque like it was made of plastic.  This tip assumes your component to be of rectangular shape and completely opaque.   (CODE)
Java contains several comparison operators (e.g., <, <=, >, >=, ==, !=) that allow you to compare primitive values. However, these operators cannot be used to compare the contents of objects. Interface Comparable is used to allow objects of a cl…
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …

920 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

14 Experts available now in Live!

Get 1:1 Help Now