Spring MVC 3:为ManyToMany添加表单关系抛出BindingResult Exception

时间:2011-06-21 11:20:17

标签: jsp spring-mvc

我有一个与角色实体有@ManyToMany关系的帐户实体。 (这样我就可以拥有一个具有多个角色的帐户。)

在我的Account.java(实体)中,我已经定义了如下关系:

@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "Account_Role", joinColumns = { 
@JoinColumn(name = "Account_id") }, 
inverseJoinColumns = { @JoinColumn(name = "Role_id") })
private List<Role> roles = new ArrayList<Role>(0);

在我的AccountController中,我有以下GET和POST操作:

@RequestMapping(value="/add", method=RequestMethod.POST)
public String add(Account item, BindingResult bindingResult, Model model, HttpServletRequest request) 
{       
  accountService.save(item);
  return "redirect:/account/list";
}

@RequestMapping(value="/add", method=RequestMethod.GET)
public String addForm(Model model) {
  model.addAttribute("item", new Account());
  model.addAttribute("roleList", roleService.list());

return "account/add";
}

我的add.jsp表单视图如下所示:

<form method="post">
<table>
    .....

    <tr>
        <td style="width:75px">
            <label for="roles"><spring:message code="labels.account.form.roles" text="Roles" /></label>
        </td>
        <td>
            <form:select path="roles" multiple="true" items="${roleList}" itemLabel="name" itemValue="id"/>
        </td>
    </tr>
    <tr>
        <td></td>
        <td>
            <input id="submitbutton" type="submit" value="<spring:message code="labels.form.button.add" text="Save" />" style="width:100%;">
        </td>
    </tr>
</table>

当我尝试打开添加对话框以输入新帐户时,我总是会收到以下错误:

SEVERE: Servlet.service() for servlet [spring] in context with path [/eLearning] threw exception [Request processing failed; nested exception is org.apache.tiles.impl.CannotRenderException: ServletException including path '/WEB-INF/views/template/layout.jsp'.] with root cause
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'roles' available as request attribute

我真的很感激能得到某人的帮助。我在访问Attribute Entity的其他字段时没有任何问题。它只是“角色” - 导致问题的属性。因为如果我从添加jsp表单中注释掉它,那么一切正常:S。

感谢您的帮助。

编辑:

感谢您的帮助。我不再得到例外了。我现在如何获取角色的价值? 如果我尝试访问Controller中的item.getRoles(),我会得到一个空列表。如何安排通过选择列表选择的角色存储在帐户实体的角色列表中?

解决第二个问题:

必须向控制器添加自定义绑定器:

@InitBinder
protected void initBinder(WebDataBinder binder) throws Exception {
    binder.registerCustomEditor(Set.class, "roles", new CustomCollectionEditor(Set.class) {
        protected Object convertElement(Object element) {
            if (element instanceof Role) {
                return element;
            }
            if (element instanceof String) {
                return roleService.load(Long.valueOf(element.toString()));
            }
            return null;
        }
    });
}

2 个答案:

答案 0 :(得分:1)

rolesAccount的属性,因此您需要将表单绑定到类型Account的模型属性以修改其属性:

<form:form method="post" modelAttribute = "item">...</form:form>

另请注意,如果模型属性名称(在您的情况下为item)与其类名称(account)不同,则需要明确指定属性名称:

public String add(@ModelAttribute("item") Account item, BindingResult bindingResult, Model model, HttpServletRequest request)   { ... }

答案 1 :(得分:0)

要使用<form:select,您需要<form:form modelAttribute="account">