public static <O extends Object> O copyFields(Class<?> clazz, Object input, O output, boolean copyCollections, 
			Collection<String> ignoreFields, boolean ignoreNonExisiting) {
		
		if (null == clazz) {
			clazz = input.getClass();
		}
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			/*
			 *  do not copy collections because of possible
			 *  org.hibernate.HibernateException: Found shared references to a collection
			 */
			if (ReflectUtils.isNotStatic(field)) {
				if (null != ignoreFields && ignoreFields.contains(field.getName())) {
					if(LOGGER.isTraceEnabled()) {
						LOGGER.trace(String.format("ignoring field: %s", field.getName()));
					}
					continue;
				}
				if (Collection.class.isAssignableFrom(field.getType()) && !copyCollections) {
					if(LOGGER.isTraceEnabled()) {
						LOGGER.trace(String.format("skipping collection field: %s", field.getName()));
					}
					continue;
				}
				if(LOGGER.isTraceEnabled()) {
					LOGGER.trace(String.format("copying field: %s, with value: %s", field.getName(), ReflectUtils.invokeGetter(input, field)));
				}
				ReflectUtils.copy(input, output, field.getName(), ignoreNonExisiting);
			}
		}
		Class<?> superClazz = clazz.getSuperclass();
		if (null != superClazz && !superClazz.isAssignableFrom(Object.class)) {
			output = copyFields(superClazz, input, output, copyCollections, ignoreFields, ignoreNonExisiting);
		}
		return output;
	}
public static < O extends Object > O copyFields ( Class < ? > clazz , Object input , O output , boolean copyCollections , Collection < String > ignoreFields , boolean ignoreNonExisiting ) { if ( null == clazz ) { clazz = input . getClass ( ) ; } Field [ ] fields = clazz . getDeclaredFields ( ) ; for ( Field field : fields ) { if ( ReflectUtils . isNotStatic ( field ) ) { if ( null != ignoreFields && ignoreFields . contains ( field . getName ( ) ) ) { if ( LOGGER . isTraceEnabled ( ) ) { LOGGER . trace ( String . format ( "ignoring field: %s" , field . getName ( ) ) ) ; } continue ; } if ( Collection . class . isAssignableFrom ( field . getType ( ) ) && ! copyCollections ) { if ( LOGGER . isTraceEnabled ( ) ) { LOGGER . trace ( String . format ( "skipping collection field: %s" , field . getName ( ) ) ) ; } continue ; } if ( LOGGER . isTraceEnabled ( ) ) { LOGGER . trace ( String . format ( "copying field: %s, with value: %s" , field . getName ( ) , ReflectUtils . invokeGetter ( input , field ) ) ) ; } ReflectUtils . copy ( input , output , field . getName ( ) , ignoreNonExisiting ) ; } } Class < ? > superClazz = clazz . getSuperclass ( ) ; if ( null != superClazz && ! superClazz . isAssignableFrom ( Object . class ) ) { output = copyFields ( superClazz , input , output , copyCollections , ignoreFields , ignoreNonExisiting ) ; } return output ; }
will copy fields with same declaration name<br>

@param clazz the starting/root class of input (maybe input class is wrapped by spring, hibernate or another framework so you should define the root class)
@param input the input object
@param output the object to fill / override
@param copyCollections if collections should be copied
(if true you may get a <code>org.hibernate.HibernateException: Found shared references to a collection</code> on entities)
@param ignoreFields list of field names to ignore
@param ignoreNonExisiting do not throw NPE if setter on output doesn't exists