在Spring MVC表单绑定集方面需要帮助


问题内容

我已经尝试了最近三天,但仍然无法解决我的问题

我有个人班

@SuppressWarnings("rawtypes")
 @OneToMany(cascade = CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="person")
 @JoinColumn(name="person_id")
 public Set<Book> books = new HashSet<Book>();

class Book

book_id
person_id

在我的JSP表格中

<c:forEach items="${BookList}" var="var1" varStatus="counter">
     <input type="checkbox" name="books[${counter.index}].book_id" value="${var1.book_id}" >${var1.book_name}</input>
    </c:forEach>

我要根据复选框在表格中插入书籍。书籍列表是从refrenceData模型填充的。

控制器

@RequestMapping(value = "/persons/add", method = RequestMethod.GET)
    public String getAdd(Model model) {
        logger.debug("Received request to show add page");

        // Create new Person and add to model
        // This is the formBackingOBject
        model.addAttribute("personAttribute", new Person());

        // This will resolve to /WEB-INF/jsp/addpage.jsp
        return "hibernate/addpage";
    }



@RequestMapping(value = "/persons/add", method = RequestMethod.POST)
public String add(@Valid @ModelAttribute("personAttribute") Person person, BindingResult result) {
        logger.debug("Received request to add new person");

        if (result.hasErrors()) 
    return "hibernate/addpage";
        else
        personService.add(person);

    // This will resolve to /WEB-INF/jsp/addedpage.jsp
        return "hibernate/addedpage";
    }

现在,如果我只有一个Book对象,则可以正常工作,并且将数据输入到DB中,但是如果我已设置,则它表示无效的属性书[1]

在SO和Google上搜索很多之后,我有两种选择

PropertyEditor
AutoPopulatingList

我不知道该如何使用它们。谁能帮助我,我在哪里必须使用它们以及如何使用它


问题答案:

查看此问题将对象绑定到Set集合中

您需要使用其他类型的集合。我建议使用列表而不是地图。当您从表单发送带有以下名称的参数时:

name="books[0].book_id"

SpringMVC将查找名为books的属性(为您设置Set),然后它将尝试通过执行books.get(0)来获取第一个元素。Set没有得到订单,因为Set没有订单。

对于列表的实现,可以使用AutoPopulatingList。它是一个惰性列表的实现,如果不存在该对象,它将创建一个对象。例如,如果您调用books [0]
.id,并且尚未在列表的位置0添加书,则它将抛出NullPointerException,但是如果您使用AutoPopulatingList,它将创建一个新的Book并将其添加到该位置。该职位是空的。

public List<Book> books = new AutoPopulatingList<Book>(new ElementFactory<Book>() {
    @Override
    public Book createElement(final int index) throws ElementInstantiationException {
         //call the constructor as you need
         return new Book();
    }       
});

如果要使用Book的默认构造函数(即Book())实例化它,则可以使用如下语法:

public List<Book> books = new AutoPopulatingList<Book>(Book.class);