У меня есть веб-приложение.
Фрагмент кода ниже.
Объекты: Меню, Блюдо
@Entity
@Table(name = "menus")
public class Menu {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int id;
@Column(name = "name")
private String name;
@Column(name = "date")
private LocalDateTime date;
@Column(name = "total_cost")
private double cost;
@ManyToOne(cascade = {
CascadeType.DETACH, CascadeType.MERGE,
CascadeType.PERSIST, CascadeType.REFRESH})
@JoinColumn(name = "restaurant_id")
private Restaurant restaurant;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "menu", cascade = CascadeType.ALL)
private Set<Dish> dishes = new HashSet<>();
@OneToMany(fetch = FetchType.EAGER, mappedBy = "menu", cascade = CascadeType.ALL)
private Set<Vote> votes;
public Menu() {
}
public Menu(String name, LocalDateTime date, double cost, Restaurant restaurant) {
this.name = name;
this.date = date;
this.cost = cost;
this.restaurant = restaurant;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Restaurant getRestaurant() {
return restaurant;
}
public void setRestaurant(Restaurant restaurant) {
this.restaurant = restaurant;
}
public Set<Dish> getDishes() {
return dishes;
}
public List<Dish> getDishesAsList(){
return new ArrayList<>(dishes);
}
public void setDishes(Set<Dish> dishes) {
this.dishes = dishes;
}
public Set<Vote> getVotes() {
return votes;
}
public void setVotes(Set<Vote> votes) {
this.votes = votes;
}
public LocalDateTime getDate() {
return date;
}
public void setDate(LocalDateTime date) {
this.date = date;
}
public double getCost() {
return cost;
}
public void setCost(double cast) {
this.cost = cast;
}
public int getVoteCount() {
return votes.size();
}
@Override
public String toString() {
return "Menu{" +
"id=" + id +
", name='" + name + '\'' +
", date=" + date +
", cast=" + cost +
", restaurant=" + restaurant +
", dishes=" + dishes +
", votes=" + votes +
'}';
}
}
Метод getDishesAsList (просто обернуть на Набор блюд) был создан, чтобы избежать этого исключения: org.springframework.beans.InvalidPropertyException: недопустимое свойство 'dish [0]' класса бобов [ru. icoltd.rvs.entity.Menu]: не удается получить элемент с индексом 0 из набора размером 0
=============================================== ===========================
@Entity
@Table(name = "dishes")
public class Dish {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int id;
@Column(name = "description")
private String description;
@Column(name = "price")
private double price;
@ManyToOne(cascade = {
CascadeType.DETACH, CascadeType.MERGE,
CascadeType.PERSIST, CascadeType.REFRESH
})
@JoinColumn(name = "menu_id")
private Menu menu;
public Dish() {
}
public Dish(String description, double price, Menu menu) {
this.description = description;
this.price = price;
this.menu = menu;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public Menu getMenu() {
return menu;
}
public void setMenu(Menu menu) {
this.menu = menu;
}
@Override
public String toString() {
return "Dish{" +
"id=" + id +
", description='" + description + '\'' +
", price=" + price +
", menu=" + menu +
'}';
}
}
=============================================== ===========================
Контроллер
@Controller
@RequestMapping("/menu")
public class MenuController {
private MenuService menuService;
@Autowired
public void setMenuService(MenuService menuService) {
this.menuService = menuService;
}
@PostMapping("/save")
public String addMenu(@ModelAttribute("menu") Menu menu) {
//menu.getDishes(); always empty
menuService.saveMenu(menu);
return "redirect:/someUrl";
}
@GetMapping("/update")
public String updateMenu(@RequestParam("menuId") int menuId, Model model) {
Menu menu = menuService.getMenu(menuId);
model.addAttribute("menu", menu);
model.addAttribute("restaurantId", menu.getRestaurant().getId());
return "menu-form";
}
=============================================== ===========================
JSP PAGE
<!doctype html>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<html>
<head>
<title>
Add Menu
</title>
</head>
<body>
<h3>Add Menu</h3>
<hr>
<c:url var="save" value="/menu/save">
<c:param name="restId" value="${restaurantId}"/>
</c:url>
<form:form action="${save}" method="post" modelAttribute="menu">
<form:hidden path="id"/>
<table>
<tbody>
<tr>
<td>Name:</td>
<td><form:input path="name"/></td>
</tr>
<tr>
<td>Date:</td>
<td><form:input type="date" path="date"/></td>
</tr>
<tr>
<td><h4>List dishes:</h4></td>
</tr>
<c:forEach items="${menu.dishesAsList}" varStatus="status" var="dish">
<c:url var="deleteLink" value="/dish/delete">
<c:param name="menuId" value="${menu.id}"/>
<c:param name="dishId" value="${dish.id}"/>
</c:url>
<form:hidden path="dishes[${status.index}].id" value="${dish.id}"/>
<tr>
<td>Dish #${status.index}</td>
<td><form:input path="dishes[${status.index}].description" value="${dish.description}"/></td>
<td><a href="${deleteLink}">Delete</a></td>
</tr>
</c:forEach>
<c:url var="showFormLink" value="/dish/showFormForAdd">
<c:param name="menuId" value="${menu.id}"/>
</c:url>
<tr>
<td></td>
<td><a href="${showFormLink}">Add new dish</a></td>
</tr>
<tr>
<td><input type="submit" value="Save" class="save"/></td>
</tr>
</tbody>
</table>
</form:form>
<hr>
<p>Total cost: </p>
<p><a href="${pageContext.request.contextPath}/restaurant/${restaurantId}/menus">Back to restaurant list</a></p>
</body>
</html>
=============================================== ===========================
Вопрос : Я хочу обновить или добавить Меню вместе с Список блюд в форме. Как установить коллекцию Блюдо для сущности Меню по всей форме напрямую? Когда я пытаюсь отправить форму, поле блюда всегда пусто. Я не могу понять, какой установщик класса Menu вызывает это поле таким образом. Спасибо за вашу помощь!