【问题标题】:Spring/Hibernate and relational mappingSpring/Hibernate 和关系映射
【发布时间】:2016-03-24 17:47:19
【问题描述】:

我是 Spring MVC 和 Hibernate(以及一般数据库)的新手,所以需要一些帮助。

目前我的数据库中有 2 个表 - 预订和餐厅。 Booking 有一个外键R_id 指向Restaurant 的主键。现在我正在尝试实现一个下拉菜单,它显示数据库中的所有餐厅,当用户选择餐厅时,该值在该 Booking 数据库中设置。我希望你明白我的意思。

我的预订舱位:

@Entity
@Table(name="booking")
public class Booking {

    @Id
    @Column(name="id")
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Long id;

    @ManyToOne
    @JoinColumn(name="R_id")
    private Restaurant restaurant;

    @Column(name="date")
    @Type(type="date")
    private Date date;

    @Column(name="start")
    @Type(type="time")
    private Date start;

    @Column(name="duration")
    private float duration;

    @Column(name="amount_of_people")
    private int amountOfPeople;

    @Column(name="name")
    private String name;

    @Column(name="contact_preference")
    private String contactPreference;

    @Column(name="comments")
    private String comments;

    @Column(name="current_datetime")
    @Type(type="timestamp")
    private Date currentDatetime;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Restaurant getRestaurant() {
        return restaurant;
    }

    public void setRestaurant(Restaurant restaurant) {
        this.restaurant = restaurant;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public Date getStart() {
        return start;
    }

    public void setStart(Date start) {
        this.start = start;
    }

    public float getDuration() {
        return duration;
    }

    public void setDuration(float duration) {
        this.duration = duration;
    }

    public int getAmountOfPeople() {
        return amountOfPeople;
    }

    public void setAmountOfPeople(int amountOfPeople) {
        this.amountOfPeople = amountOfPeople;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getContactPreference() {
        return contactPreference;
    }

    public void setContactPreference(String contactPreference) {
        this.contactPreference = contactPreference;
    }

    public String getComments() {
        return comments;
    }

    public void setComments(String comments) {
        this.comments = comments;
    }

    public Date getCurrentDatetime() {
        return currentDatetime;
    }

    public void setCurrentDatetime(Date currentDatetime) {
        this.currentDatetime = currentDatetime;
    }

}

餐厅类:

@Entity
@Table(name="restaurant")
public class Restaurant {

    @Id
    @Column(name="id")
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private Long id;

    @Column(name="restaurant_name")
    private String restaurantName;

    @Column(name="address")
    private String address;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getRestaurantName() {
        return restaurantName;
    }

    public void setRestaurantName(String restaurantName) {
        this.restaurantName = restaurantName;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String toString() {
        return restaurantName;
    }

}

MainController中的相关方法:

    @RequestMapping(value = "booking/create", method = RequestMethod.GET)
    public String createBooking(Model model) {
        model.addAttribute("booking", new Booking());
        initModelList(model);
        return "newBooking";
    }

    @RequestMapping(value = "booking/create", method = RequestMethod.POST)
    public String createBookingAction(Booking booking) {
        bookingService.addBooking(booking);
        return "redirect:/bookings";
    }

     .....

    private void initModelList(Model model) {
    List<Restaurant> restaurantList = restaurantService.getRestaurants();
        model.addAttribute("restaurants", restaurantList);

    }

这是我的jsp文件:

<%@ page contentType="text/html; charset=UTF-8" %>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<!DOCTYPE html>
<html lang="en">
<jsp:include page="../fragments/head.jsp"/>
<body>
<jsp:include page="../fragments/menu.jsp"/>
<div id="body">
    <h2>Create new booking</h2>

    <form:form method="POST" commandName="booking" class="bookingForm">
        <table>
            <tr>
                <td>Restaurant:</td>
                <td><form:select path="restaurant">
                    <form:option value="NONE" label="--- Select ---" />
                    <form:options items="${restaurants}" />
                </form:select>
                </td>
            </tr>
            <tr>
                <td colspan="3"><input type="submit" /></td>
            </tr>
        </table>
    </form:form>
    <div>
        <a href="/bookings">Back to List</a>
    </div>
</div>
<jsp:include page="../fragments/footer.jsp"/>

</body>
</html>

现在下拉菜单显示餐厅,但是当我点击提交时,它给了我这个错误:The request sent by the client was syntactically incorrect.

我认为这是因为 Booking 和 Restaurant 之间的映射有问题,但我不知道它是什么。对不起,很长的帖子,任何帮助表示赞赏。谢谢!

【问题讨论】:

    标签: java database spring hibernate spring-mvc


    【解决方案1】:

    您的控制器booking/create POST 在您从JSP 表单发送的请求中期待一个有效的Booking 对象。

    你可以试试改

    <form:select path="restaurant">
    

    <form:select path="restaurant.restaurantName">
    

    由于表单本身会将内容添加到预订对象,因此该字段将有效地映射到booking.restaurant.restaurantName,这使其成为有效的预订对象。

    另外请注意,此时您的控制器将获得一个预订对象,其中只有一个字段包含数据。在保存数据之前,您需要从 db 中获取相关对象的其余数据(如 id)。

    【讨论】:

    • 而不是restaurentName,它可能是id,我有点困惑.. 两个都试试
    • 非常感谢!
    【解决方案2】:

    考虑使用专用表单,这是一种很好的做法。

    在您的情况下,它将是一个名为 BookingAddForm 的专用用户类,具有 IntegerString 等原始数据类型,包括包含操作所需的唯一信息的集合,在您的情况下是餐厅名称列表。因此,不再需要简单的复杂对象列表绑定,并且一切正常。

    之后,就可以在服务层轻松处理​​了。从您加载的数据中创建您的 Hibernate 实体并根据需要进行处理。数据检索也是如此。


    在您指定的代码中,您错过了将表单与控制器关联的 @ModelAttribute 注释。应该是这样的:

    @RequestMapping(value = "booking/create", method = RequestMethod.POST)
    public String createBookingAction(@ModelAttribute @Valid BookingAddForm bookingAddForm, BindingResult br) {
    
        // validation required!
        bookingService.addBooking(bookingAddForm);
    
        return "redirect:/bookings";
    } 
    

    ... 另请注意,您不执行任何验证。您必须这样做,否则您的应用程序不安全。

    @Valid annotation

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-08
      • 2018-07-11
      • 2020-01-16
      • 2020-10-11
      • 2020-12-04
      • 2013-05-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多