INITIAL QUESTION (UPDATED BELOW)
I'm using an AutoPopulatingList
list to instatiate an object invoking a constructor with some parameters. Something like the code below. I had used it before without any problems but I can't get it working now.
public class Tree {
...
private List<Node> nodes = new AutoPopulatingList<Node>(new ElementFactory<Node>() {
@Override
public Node createElement(final int index) throws ElementInstantiationException {
//call custom controller
return new Node(index, ...other params);
}
});
...
//getters & setters
}
The object is mapped in a controller as a model attribute param (@ModelAttribute Tree
). So I send in the form values like:
nodes[0].field1 = some value
nodes[1].field2 = other value
But when I send these parameters spring cannot instantiate the Node
object because it's looking for a constructor without params for Node
object, and it throws an Exception like the following:
org.springframework.beans.NullValueInNestedPathException: Invalid property 'nodes' of bean class [...Node]: Could not instantiate property type [...Node] to auto-grow nested property path: java.lang.InstantiationException: ...Node.()
If I add a constructor without params to Node
class there is no error, but when I send nodes[0]
it is invoked Node()
instead of using the ElementFactory
provided.
The weird thing is that if I do in the controller treeObject.getNodes().get(0)
, the constructor invoked is the one with params (as it should be).
I'm using Spring 3.0.4.RELEASE.
Does anybody knows why can this be happening? Can this be a bug?
Thanks.
UPDATE
I have build a custom implementation of a List similar to AutoPopulatingList to check if this was a problem of AutoPopulatingList, but it happens the same behaviour. The implementation just overrides:
public Node get(int index) {
//here just creates the object it it doesn't exist in the position
}
So the problem is why when I do in a controller:
public String controllerMethod(
@ModelAttribute Tree tree, BindingResult result, Model model){
...
}
and I send nodes[0].something as there isn't any object in the position 0 of index it has to instance the object. But the problem is that it is invoked Node() constructor before invoking tree.get(0). So, Why does Spring invokes the default constructor? How can I force it to use tree.get(0) to instance the object instead of Node()?
I've solved it by disabling the autogrownestedpaths in the binder, so this allows Autopopulating list will take care of auto-growing with its own factory.
@InitBinder
public void initBinder(WebDataBinder binder){
binder.setAutoGrowNestedPaths(false);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With