I am creating a one to many relationship, where Category has many Products. After listingn all my existing categories,I want to see all the products in a specifc category and to do basic CRUD on those products(from that category). I find dificulties in redirecting pages in Thymealeaf, most exactly I can't acces the "Add Product" page, using Thymeleaf.
@Entity
@Table(name="category")
public class Category {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
@Column(name="id")
private long id;
@Column
@NotEmpty(message = "*Please provide a description")
private String description;
@OneToMany(mappedBy = "category")
private Set<Product> products;
public Category(){}
@Entity
@Table(name="product")
public class Product {
@Id
@Column(name="id")
private String id;
@Column
private String name;
@Column
private String description;
@Column
private float price;
@Column
private int discount;
@Column
private boolean isInStock;
@ManyToOne
@JoinColumn(name="category_id")
private Category category;
Here is my my way of saving products in Service layer
public Product save(Product product, long id) {
Category category = categoryRepository.getById(id);
if (category != null) {
product.setId(UUID.randomUUID().toString());
product.setCategory(category);
product.setInStock(false);
return productRepository.save(product);
} else {
throw new ResourceNotFoundException("Category not found with id: " + id);
}
}
In controller I have:
@Autowired
ProductService productService;
@GetMapping("/products/{categoryId}")
public String viewProducts(Model model, @PathVariable("categoryId") long categoryId) {
List<Product> productsList = productService.findByCategoryId(categoryId);
model.addAttribute("productsList", productsList);
model.addAttribute("categoryId",categoryId );
return "products";
}
@GetMapping("/newProduct/{categoryId}")
public String showAddForm(Model model,@PathVariable("categoryId") long categoryId) {
Product product = new Product();
model.addAttribute("product", product);
return "newProduct";
}
@PostMapping("/save/{categoryId}")
public String addProduct(@ModelAttribute("product") Product product, @PathVariable long categoryId){
productService.save(product, categoryId);
return "redirect:products";
}
Where I am stuck is that I can't redirect from products.html to newProduct.html (that showAddForm method should return) using the path variable categoryId.It redirects me to an error page where if I enter the categoryId by hand in the URL,I finally get to the newProduct.html. In the products.html, I have:
<body>
<div class="container my-2">
<div class="card">
<div class="card-body">
<!-- TODO get category ID from categories (parameters between HTML)-->
<div th:switch="${productsList}" class="container my-5">
<p class="my-5">
<a href="/product/newProduct/" class="btn btn-primary">Add product</a>
</p>
<div class="col-md-10">
<h2 th:case="null">No Products yet!</h2>
<div th:case="*">
<table class="table table-striped table-responsive-md">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Price</th>
<th>Discount</th>
<th>IsInStock</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<tr th:each="product : ${productsList}">
<td th:text="${product.name}"></td>
<td th:text="${product.description}"></td>
<td th:text="${product.discount}"></td>
<td th:text="${product.price}"></td>
<td th:text="${product.isInStock}"></td>
<td><a th:href="@{/product/edit/{id}(id=${product.id})}" class="btn btn-primary"></a></td>
<td><a th:href="@{/product/delete/{id}(id=${product.id})}" class="btn btn-primary"></a></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
The issue I see is, your code for showAddForm
with the path @GetMapping("/newProduct/{categoryId}")
is expecting a catgoryID which is not sent in the above Add product button. Since you are passing a categoryId in the line model.addAttribute("categoryId",categoryId );
you can use this in the href element. Therefore, that link should be something like
<p class="my-5">
<a th:href="@{/product/newProduct(categoryId=${categoryId})}" class="btn btn-primary">Add product</a>
</p>
But since within the method showAddForm
categoryID is not used, so you can remove that. And try with something like
<p class="my-5">
<a th:href="@{/product/newProduct}" class="btn btn-primary">Add product</a>
</p>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.