?
Solved

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

Posted on 2011-09-21
19
Medium Priority
?
701 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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:Gurvinder Pal Singh
ID: 36578645
why don't you override the copyProperties method of BeanUtils after extending the same
0
 
LVL 40

Accepted Solution

by:
Gurvinder Pal Singh earned 1000 total points
ID: 36578650
0
Get 15 Days FREE Full-Featured Trial

Benefit from a mission critical IT monitoring with Monitis Premium or get it FREE for your entry level monitoring needs.
-Over 200,000 users
-More than 300,000 websites monitored
-Used in 197 countries
-Recommended by 98% of users

 
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:Gurvinder Pal Singh
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
 
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 1000 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

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

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

In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
In this post we will learn how to make Android Gesture Tutorial and give different functionality whenever a user Touch or Scroll android screen.
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 about basic arrays, how to declare them, and how to use them. Introduction and definition: Declare an array and cover the syntax of declaring them: Initialize every index in the created array: Example/Features of a basic arr…
Suggested Courses
Course of the Month12 days, 16 hours left to enroll

777 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