How to send an object with model including its child object
I wants to add new product object with its category. Product object successfully sent but its category (inside product) is null. What is error that category is not able to send. How can I fix it? Code inside @Controller
.
@GetMapping("/loadForm") public String addNewProduct(Model model){ Product theProduct = new Product(); List<Category> categories = (List<Category>) categoryService.findAll(); model.addAttribute("categories", categories); model.addAttribute("product", theProduct); return "addProduct"; } @PostMapping(value="/add") public String addProduct(@ModelAttribute("product") Product product) { System.out.println("Checking"); productService.insert(product); return "product"; }
Code inside HTML file is
<form th:action="@{/products/add}" th:object="${product}" method="POST"> <input type="hidden" value="100" th:field="*{productId}"/><br> <input type="text" th:field="*{barcode}" class="form-control mb-4 col-10" placeholder="barcode"><br><br> <input type="text" th:field="*{createdUser}" class="form-control mb-4 col-10" placeholder="created User"><br><br> <input type="text" th:field="*{lastModifiedUser}" class="form-control mb-4 col-10" placeholder="last Modified User"><br><br> <input type="text" th:field="*{productIsService}" class="form-control mb-4 col-10" placeholder="product Is Service"><br><br> <input type="text" th:field="*{productName}" class="form-control mb-4 col-10" placeholder="product name"><br><br> <input type="text" th:field="*{productbuyingPrice}" class="form-control mb-4 col-10" placeholder="product buying Price"><br><br> <input type="text" th:field="*{productsellingPrice}" class="form-control mb-4 col-10" placeholder="product selling Price"><br><br> <input type="text" th:field="*{version}" class="form-control mb-4 col-10" placeholder="version"><br><br> <select th:field="*{category}" class="form-control mb-4 col-10" placeholder="Select category"> <option th:each="tempCategory : ${categories}" th:value="${tempCategory}" th:text="${tempCategory.categoryName}"></option> </select> <button type="submit" class="btn btn-info col-4">Save</button> </form>
And relation between product and category is many to one. Code in Product class
@ManyToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST,CascadeType.REFRESH}) @JoinColumn(name="category_id") private Category category;
Code in category class
@JsonIgnore @OneToMany(mappedBy="category") private List<Stock> stocks;
In your scenario, for one product there will be multiple categories. The mapping should be oneToMany.
In Product class:
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @JoinColumn(name="category_id") Set<Category> categories;
In Category class:
@JoinColumn(name = "category_id") @ManyToOne(cascade = CascadeType.ALL) private Product product;
I just add cascade
and fetch
into category id. I Replace this:
@JsonIgnore @OneToMany(mappedBy="category") private List<Stock> stocks;
With This:
@OneToMany(fetch = FetchType.LAZY, mappedBy="category", cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}) public List<Product> products;
There was missing Cascade in child entity.