0

I've these two classes:

public class ServiceConfiguration {
    private String id;
    private List<Parameter> parameters;
}

public class ConfigurationUpdateForm {

    @NotEmpty private String id;

    @NotEmpty @Valid private Collection<ConfigurationParameterForm> parameters;
}

I need to copy all properties from an ConfigurationUpdateForm object to an ServiceConfiguration object:

ServiceConfiguration serviceConfiguration = new ServiceConfiguration();
try {
    BeanUtils.copyProperties(serviceConfiguration, configurationForm);
} catch (IllegalAccessException | InvocationTargetException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

But it doesn't copy parameters collection correctly.

What's failing is after copyProperties, destinationbean.parameters contains a list of ParameterTypeForm instead of a list of Parameter...

Any ideas?

Jordi
  • 20,868
  • 39
  • 149
  • 333
  • 3
    what do you mean doesn't copy correctly? what is the error? perhaps it is because the two variables arenot defined the same? – Sharon Ben Asher Nov 27 '18 at 12:08
  • 1
    Use another library, like [Dozer](http://dozer.sourceforge.net/). There is a list of [alternate](https://stackoverflow.com/questions/1432764/any-tool-for-java-object-to-object-mapping) solutions . – Victor Gubin Nov 27 '18 at 12:09
  • After `copyProperties`, `destinationbean.parameters` contains a list of `ParameterTypeForm` instead of a list of `Parameter`... – Jordi Nov 27 '18 at 12:12

1 Answers1

0

BeanUtils.copyProperties(serviceConfiguration, configurationForm) will just copy all the bean properties of one class to the other for all cases where the name is the same.

As both classes contain the parameters property, BeanUtils will just copy the value.

And that is exactly what is happening in your result, suddenly the parameters inside ServiceConfiguration contains a list of ConfigurationParameterForm objects.

This is because the copying is only being done one level deep and also because at runtime nothing is preventing a List to contain objects of different classes than those you specified in the declaration.

In example:

public class Dog {
    @Override
    public String toString() {
        return "I'm a dog";
    }
}

public class Cat {
    @Override
    public String toString() {
        return "I'm a cat";
    }
}

public static void main(String[] args) {
    List<Dog> dogs = new ArrayList<>();
    dogs.add(new Dog());

    addCat(dogs);

    System.out.println(dogs);
}

public static void addCat(List cats) {
    cats.add(new Cat());
}

Running the above code will result in: [I'm a dog, I'm a cat]

A possible solution would be to add your own mapping method that will map from one class to the other using getters and setters, but you will also need a mapping from: ConfigurationParameterForm to Parameter