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

           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?
LVL 20
chaitu chaituAsked:
Who is Participating?
 
reijnemansCommented:
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
 
Gurvinder Pal SinghCommented:
why don't you override the copyProperties method of BeanUtils after extending the same
0
Cloud Class® Course: CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

 
reijnemansCommented:
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
 
chaitu chaituAuthor Commented:
my question title little bit wrong .Destination bean values should not lose if already exists.
0
 
Gurvinder Pal SinghCommented:
Thats why either you should write your own copier or override beanutils copy properties method
0
 
chaitu chaituAuthor Commented:
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
 
reijnemansCommented:
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
 
chaitu chaituAuthor Commented:
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
 
reijnemansCommented:
writing you're own copy class
0
 
chaitu chaituAuthor Commented:
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
 
reijnemansCommented:
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
 
chaitu chaituAuthor Commented:
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
 
reijnemansConnect With a Mentor Commented:
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
 
chaitu chaituAuthor Commented:
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
 
reijnemansCommented:
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
 
reijnemansCommented:
But propbably you don't have a DynaBean so it is not necessary. And you could remove the code
0
 
chaitu chaituAuthor Commented:
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
 
reijnemansCommented:
you're right the copyProperties I posted was a private method :-O. So problem solved?
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.