在提交Spring MVC上绑定子对象


问题内容

我是Java的新手,所以这个问题看起来很简单。我有一个像这样的模型:

@Entity(name="website")
public class Website {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="websiteId", nullable=false, unique=true)
private long websiteId;
@ManyToOne
@JoinColumn(name = "publisherId")
private Publisher publisher;

public Website() {
}

//... all getter and setter....
}

您会看到,在Website类中,我有一个Publisher类型的对象:

@Entity(name="publisher")
public class Publisher {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="publisherId", nullable=false, unique=true)
private long publisherId;
private String publisherName;

@OneToMany(fetch=FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name="publisherId")
private List<Website> listWebsite;

public Publisher() {
}

//...all getter and setter...
}

好的,现在我有一个表单来提交网站类型的整个对象。我刚刚创建了一个下拉列表,并允许用户选择发布者:表单:

<form:form action="/LineJavaTest1/website/add" commandName="websiteForm" method="post">
                <form:input path="websiteName" size="30" placeholder="Website Name"/>
                <form:input path="websiteUrl" size="30" placeholder="Website Url"/>
                <form:select path="publisher" multiple="false" size="1">
                    <%--<form:options itemValue="publisherId" itemLabel="publisherName"/>--%>
                    <form:option value="NONE" label="--- Select ---" />
                    <form:options items="${publishers}" itemValue="publisherId" itemLabel="publisherName"/>
                </form:select>
                <form:hidden path="websiteId" size="30" placeholder="Website Id"/>
                <input type="submit" class="btn btn-default" value="Save" />
            </form:form>

您会看到,我将form:select标记的路径设置为“ publisher”,itemValue设置为“
publisherId”。发布时,它将PublisherId(长型值)发布到发布对象的Publisher属性中。验证将失败,因为它需要Publisher类型,而不是long类型。

我的问题:如何以正确的方式发布Website.Publisher.publisherId?

更新:

我在控制器中的添加操作:

@RequestMapping(value = "/add", method = RequestMethod.GET)
public String showForm(ModelMap mm, @ModelAttribute("websiteForm") Website websiteForm) {
    mm.put("websiteForm", new Website());
    mm.put("publishers", publisherService.getAll());
    return "website/add";
}

@RequestMapping(value = "/add", method = RequestMethod.POST)
public String add(@ModelAttribute("websiteForm") Website websiteForm, BindingResult result, ModelMap mm) {
    websiteValidator.validate(websiteForm, result);
    if (result.hasErrors()) {
        return "error";
    }

    if (websiteForm.getWebsiteId()>0) {
        websiteService.edit(websiteForm);
    }else
    {
        websiteService.add(websiteForm);
    }
    return "redirect:index";
}

我将选择标签的路径从Shantaram Tupe
publisher更改publisher.publisherId为如下所示,但是无法将表单生成为html。我从更改publisherpublisher.publisherName,一切看起来都不错,可以用html查看表单,将值发回到服务器中publisher.publisherName。我如何才能将其重新寄回publisher.publisherId?我的PublisherId字段的配置看起来有问题吗?

更新2

我的问题是仅生成HTML表单。我曾尝试在浏览器上通过类似以下方式编辑生成的HTML表单:

<form.....>
<select id="publisher.publisherName" name="publisher.publisherName" size="1">......</select>
</form>

像这样:

<form.....>
<select id="publisher.publisherId" name="publisher.publisherId" size="1">......</select>
</form>

一切正常。现在,我该如何生成表格publisher.publisherId

最后更新

终于,我找到了。它与PublisherName一起使用,但不适用于PublisherId,因为PublisherName是字符串类型。我使用的选择标记(<form:option value="NONE" label="--- Select ---" />)中的转储项具有值NONE-不能为长型值。将其更改为0并且成功生成了表单。


问题答案:

只需将<form:select>标记中的路径从更改 publisherpublisher.publisherId

我这边还有一些事情:

  1. 你不需要用 @Column(name="websiteId", nullable=false, unique=true)

    • 由于您在数据库中具有与实体类中的字段名称相同的列名称
    • 由于带有注释,@Id因此永远不会为 空, 并且默认情况下为 uniqe
    • 您不需要@JoinColumn@OneToMany两侧都使用,在一侧使用 mapledBy 属性,例如@OneToMany(mappedBy="publisher")