У меня есть веб-приложение. Фрагмент кода ниже.
Сущности: Меню, Блюдо
@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: Неверное свойство 'тарелки[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-СТРАНИЦА
<!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 вызывает это поле таким образом. Спасибо за вашу помощь!
@Aris_Kortex, я поделился кодом для сущностей и jsp. Насчет stacktrace: исключений нет.
Возможный дубликат Как сохранить много объектов в пружине <form:form>
@Aris_Kortex Здесь та же проблема, но ответа нет




Не могли бы вы поделиться всем своим кодом и полной трассировкой стека?