绑定动态列表时的奇怪问题

时间:2011-01-11 12:28:45

标签: java spring collections spring-mvc constructor

初步问题(更新如下)

我正在使用AutoPopulatingList列表来设置一个对象,该对象使用一些参数调用构造函数。类似下面的代码。我之前没有遇到任何问题,但我现在无法使用它。

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
}

对象在控制器中映射为模型属性参数(@ModelAttribute Tree)。所以我发送的表格值如下:

nodes[0].field1 = some value
nodes[1].field2 = other value

但是当我发送这些参数时,spring无法实例化Node对象,因为它正在查找没有Node对象的参数的构造函数,并且它会抛出如下的异常:

  

org.springframework.beans.NullValueInNestedPathException:bean类[... Node]的属性'nodes'无效:无法实例化属性类型[... Node]以自动增长嵌套属性路径:java.lang.InstantiationException :...节点。()

如果我将没有参数的构造函数添加到Node类,则没有错误,但是当我发送nodes[0]时,会调用Node()而不是使用提供的ElementFactory

奇怪的是,如果我在控制器treeObject.getNodes().get(0)中执行,则调用的构造函数是具有params的构造函数(应该是)。

我正在使用Spring 3.0.4.RELEASE。

有人知道为什么会这样吗?这可能是个错误吗?

感谢。


更新

我已经构建了类似于AutoPopulatingList的List的自定义实现,以检查这是否是AutoPopulatingList的问题,但它发生了相同的行为。 实施只是覆盖:

public Node get(int index) {
    //here just creates the object it it doesn't exist in the position
}

所以当我在控制器中进行操作时,问题就出现了原因:

public String controllerMethod(
@ModelAttribute Tree tree, BindingResult result, Model model){
     ...
}

并且我发送节点[0] .something,因为索引的位置0中没有任何对象,它必须实例化该对象。但问题是它在调用tree.get(0)之前调用了Node()构造函数。那么,为什么Spring会调用默认的构造函数呢?如何强制它使用tree.get(0)来实例化对象而不是Node()?

1 个答案:

答案 0 :(得分:15)

我已经通过禁用活页夹中的自动增长路径解决了这个问题,因此这允许自动填充列表将负责自己的工厂自动增长。

@InitBinder
public void initBinder(WebDataBinder binder){
    binder.setAutoGrowNestedPaths(false);
}