Странная проблема при привязке динамического списка
НАЧАЛЬНЫЙ ВОПРОС (ОБНОВЛЕНО НИЖЕ)
Я использую список 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
}
Объект сопоставляется в контроллере как параметр param модели (@ModelAttribute Tree
). Поэтому я отправляю значения формы, например:
nodes[0].field1 = some value
nodes[1].field2 = other value
Но когда я отправляю эти параметры, spring не может создать экземпляр объекта Node
, потому что он ищет конструктор без параметров для объекта Node
, и он выдает исключение, подобное следующему:
org.springframework.beans.NullValueInNestedPathException: Недопустимые "узлы" свойств bean class [... Node]: не удалось создать тип свойства [... Node] для автоматического создания пути вложенного свойства: java.lang.InstantiationException:... Узел.()
Если я добавлю конструктор без параметров в класс Node
, ошибки нет, но когда я отправляю nodes[0]
, он вызывается Node()
вместо использования ElementFactory
.
Странно, что если я делаю в контроллере treeObject.getNodes().get(0)
, вызываемый конструктор - это тот, у кого есть параметры (как и должно быть).
Я использую spring 3.0.4.RELEASE.
Кто-нибудь знает, почему это может произойти? Может ли это быть ошибкой?
Спасибо.
UPDATE
Я создал собственную реализацию List, подобную AutoPopulatingList, чтобы проверить, была ли это проблема 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 индекса нет объекта, который должен иметь экземпляр объекта. Но проблема в том, что он вызывается конструктором Node() перед вызовом tree.get(0). Итак, почему spring вызывает конструктор по умолчанию? Как я могу заставить его использовать tree.get(0) для экземпляра объекта вместо Node()?
Ответы
Ответ 1
Я решил это, отключив autogrownestedpaths в связующем, так что это позволяет Autopopulating list позаботиться об автоматическом росте со своим собственным factory.
@InitBinder
public void initBinder(WebDataBinder binder){
binder.setAutoGrowNestedPaths(false);
}