需要帮助绑定Set与Spring MVC表单

4 java data-binding spring-mvc

我一直在尝试过去3天仍然无法解决我的问题

我有人类

@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
Run Code Online (Sandbox Code Playgroud)

在我的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>
Run Code Online (Sandbox Code Playgroud)

我根据复选框将书籍插入表格中.书籍列表是从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";
    }
Run Code Online (Sandbox Code Playgroud)

现在,如果我有单个Book对象,那么这个工作正常,数据输入DB,但如果我已经设置,那么它表示无效的属性书[1]

在搜索了很多关于SO和Google之后,我知道我有两个选择

PropertyEditor
AutoPopulatingList
Run Code Online (Sandbox Code Playgroud)

在我的情况下,我不知道如何使用它们.任何人都可以帮助我,我在哪里使用它们以及如何使用它

Jav*_*avi 8

看看这个问题在Set集合中绑定对象

您需要使用其他类型的Collection.我建议使用List而不是Map.当您从表单发送一个名称为的参数时:

name="books[0].book_id"
Run Code Online (Sandbox Code Playgroud)

SpringMVC将查看名为books的属性(这是一个Set for you),然后它将尝试通过books.get(0)获取第一个元素.设置没有get,因为Set没有订单.

对于列表的实现,您可以使用AutoPopulatingList.它是一个惰性List的实现,如果它不存在,它将创建一个对象.例如,如果您调用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();
    }       
});
Run Code Online (Sandbox Code Playgroud)

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

public List<Book> books = new AutoPopulatingList<Book>(Book.class);
Run Code Online (Sandbox Code Playgroud)