如何将对象(带有集合)正确绑定到Spring Forms?

时间:2015-12-03 12:27:21

标签: java spring forms hibernate spring-mvc

我正在使用Spring MVCHibernate以及JSP创建Spring Forms

注释看起来像这样:

BookDescriptions.class

@Id
@Column(name = "isbn", unique = true, nullable = false)
private String isbn;

private String title;
private String description;
private String price;
private String publisher;
private String pubDate;
private String edition;
private String pages;

@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "BookAuthorsBooks", joinColumns = { @JoinColumn(name = "isbn") }, inverseJoinColumns = {
        @JoinColumn(name = "authorId") })
private Set<BookAuthors> bookAuthors;

@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "BookCategoriesBooks", joinColumns = { @JoinColumn(name = "isbn") }, inverseJoinColumns = {
        @JoinColumn(name = "categoryId") })
private Set<BookCategories> bookCategories;

@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "BookStocksBooks", joinColumns = { @JoinColumn(name = "isbn") }, inverseJoinColumns = {
        @JoinColumn(name = "stockId") })
private BookStocks bookStock;

BookStocks.class

@Id
private String stockId;
private int stock;
private Date listedDate = new Date(123L);

BookAuthors.class

@Id
@Column(name = "authorid", unique = true, nullable = false)
private String authorId;

private String nameF;

private String nameL;

BookCategories.class

@Id
@Column(name = "categoryid", unique = true, nullable = false)
private int categoryId;

private String categoryName;

因此BookDescriptions.class是父项,并且使用Join Table与其他表格有关系。

我正试图通过以下形式操纵数据库中的数据:

<c:forEach items="${bookDescriptions}" var="description">
            <tr>
                <form:form method="POST" action="updateStock"
                    modelAttribute="updatedStock">
                    <form:hidden path="isbn" value="${description.getIsbn()}" />
                    <form:hidden path="title" value="${description.getTitle()}" />
                    <form:hidden path="price" value="${description.getPrice()}" />
                    <form:hidden path="description"
                        value="${description.getDescription()}" />
                    <form:hidden path="publisher"
                        value="${description.getPublisher()}" />
                    <form:hidden path="pubDate"     value="${description.getPubDate()}" />    
                    <form:hidden path="edition"     value="${description.getEdition()}" />    
                    <form:hidden path="pages"     value="${description.getPages()}" />
                    <form:hidden path="bookAuthors"
                        value="${description.getBookAuthors()}" />
                    <form:hidden path="bookCategories"
                        value="${description.getBookCategories()}" />
                    <form:hidden path="bookStock"
                        value="${description.getBookStock()}" />
                    <form:hidden path="bookStock.stockId"
                          value="${description.getBookStock().getStockId()}" />

                    <td><c:out value="${description.getIsbn()}" /></td>
                    <td><c:out value="${description.getTitle()}" /></td>
                    <td><c:out value="${description.getBookStock().getStock()}" /></td>

                    <td><form:input path="bookStock.stock"
                                value="${description.getBookStock().getStock()}"></form:input></td>
                    <td><input type="submit" value="Save" /></td>
                </form:form>
            </tr>
        </c:forEach>

在这种情况下,它正在运作。我可以成功操作股票,但似乎我错过了将对象绑定到Spring Forms的正确方法,因为使用以下格式操作BookDescription.class中的数据无法按预期工作:

<c:forEach items="${bookDescriptions}" var="description">
            <tr>
                <form:form method="POST" action="updateStock"
                    modelAttribute="updatedBookDescription">
                    <td><form:input path="isbn" value="${description.getIsbn()}" /></td>
                    <td><form:input path="title"
                            value="${description.getTitle()}" /></td>
                    <td><form:input path="description"
                            value="${description.getDescription()}" /></td>
                    <td><form:input path="publisher"
                            value="${description.getPublisher()}" /></td>
                    <td><form:input path="price"
                            value="${description.getPrice()}" /></td>
                    <td><form:input path="pubDate"
                            value="${description.getPubDate()}" /></td>
                    <td><form:input path="edition"
                            value="${description.getEdition()}" /></td>
                    <td><form:input path="pages"
                            value="${description.getPages()}" /></td>
                    <td><form:input path="bookAuthors"
                            value="${description.getBookAuthors()}" /></td>
                    <td><form:input path="bookCategories"
                            value="${description.getBookCategories()}" /></td>
                    <td><form:input path="bookStock"
                            value="${description.getBookStock()}" /></td>

                    <form:hidden path="bookStock.stockId"
                        value="${description.getBookStock().getStockId()}" />
                    <form:hidden path="bookStock.stock"
                        value="${description.getBookStock().getStock()}" />


                    <td><input type="submit" value="Save" /></td>
                </form:form>
            </tr>
        </c:forEach>

问题如下:操纵BookDescription.class中的数据不仅会更新条目,还会删除旧条目并创建新条目。在此过程中,连接表中的条目将被删除,而不会重新输入。 似乎Spring Forms无法绑定<form:hiddenpath="bookAuthors" value="${description.getBookAuthors()}" />

我的控制器看起来像这样:

@RequestMapping(value = "/admin", method = { RequestMethod.GET, RequestMethod.POST })
public String adminPane(Model model) {

    List<BookDescriptions> resultList = bookDescriptionsDaoImpl.getAllEntries();
    model.addAttribute("bookDescriptions", resultList);
    model.addAttribute("updatedStock", new BookDescriptions());
    model.addAttribute("updatedBookDescription", new BookDescriptions());

    return "admin";
}

,输入的数据如下:

public void update(BookDescriptions bookDescription) {

    if (this.entityManager.getTransaction().isActive()) {
        this.entityManager.getTransaction().rollback();
    }
    this.entityManager.getTransaction().begin();
    this.entityManager.merge(bookDescription);
    this.entityManager.flush();
    this.entityManager.getTransaction().commit();

}

目前我有点绝望,因为我错过了HibernateSpring MVC的经验,不知道在哪里寻找问题/解决方案所以我会非常感谢关键词,解决方案或链接以便进一步阅读。 我想我走的是完全错误的道路。

提前谢谢!

更新 我正在使用persistence.xml,它看起来像这样:

<persistence-unit name="test-jpa" transaction-type="RESOURCE_LOCAL">
    <properties>
        <property name="hibernate.connection.driver_class" value="org.h2.Driver"></property>
        <property name="hibernate.connection.url" value="jdbc:h2:tcp://localhost/~/test"></property>
        <property name="hibernate.connection.username" value="sa"></property>
        <property name="hibernate.connection.password" value=""></property>
        <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"></property>
        <property name="hibernate.hbm2ddl.auto" value="update"></property>
        <property name="hibernate.show_sql" value="true"></property>
    </properties>
</persistence-unit>

1 个答案:

答案 0 :(得分:1)

尝试在代码中使用saveOrUpdate(...);update(..),如下所示:

public void update(BookDescriptions bookDescription) {

if (this.entityManager.getTransaction().isActive()) {
    this.entityManager.getTransaction().rollback();
}
this.entityManager.getTransaction().begin();
this.entityManager.update(bookDescription);
this.entityManager.getTransaction().commit();

}

或者

public void update(BookDescriptions bookDescription) {

if (this.entityManager.getTransaction().isActive()) {
    this.entityManager.getTransaction().rollback();
}
this.entityManager.saveOrUpdate(bookDescription);
}