Order management use case
Let's consider a complex scenario for this section. In the use case that we have considered, the Order use case has customer and product objects in the class. When a user places an order, the user will select a product and customer.
Our aim here is to store the customer
and product
classes directly in the Order
collection in MongoDB. Let's first implement the OrderBean
class with getter and setters.
Order.java
package com.packt.bean; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; @Document public class Order { private String order_id; private Customer customer; private Product product; private String date; private String order_status; private int quantity; public Order() { super(); // TODO Auto-generated constructor stub } @Id public String getOrder_id() { return order_id; } public void setOrder_id(String order_id) { this.order_id = order_id; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } public int getQuantity() { return quantity; } public void setQuantity(int quantity) { this.quantity = quantity; } public String getOrder_status() { return order_status; } public void setOrder_status(String order_status) { this.order_status = order_status; } public Customer getCustomer() { return customer; } public void setCustomer(Customer customer) { this.customer = customer; } public Product getProduct() { return product; } public void setProduct(Product product) { this.product = product; } }
The next step would be to define the methods in the OrderRepository.java
file.
Below are the code snippets of the update
and save
methods in the repository
class.
Creating and inserting Order
We see that the update Order
method accepts the Order
object. We used the addCriteria()
method to get a particular order based on the object ID. The Order
object retrieved is stored in the temp
object. The values are then set to the temp
object based on the object that is passed to the method. Then, the mongoTemplate.save(Object)
method is called to update the saved object.
public void updateObject(Order order) { Query query = new Query(); query.addCriteria(Criteria.where("_id").is(order.getOrder_id())); Order order_tempObj = mongoTemplate.findOne(query, Order.class); order_tempObj.setCustomer(order.getCustomer()); order_tempObj.setProduct(order.getProduct()); order_tempObj.setQuantity(order.getQuantity()); mongoTemplate.save(order_tempObj); }
The saveObject
method only accepts the Order
object and sets the ID to the Order
object before saving it.
We have seen how to perform an update and an insert. The following method is invoked to save the Order details. This shows that mongoTemplate
has the methods insert()
and save()
.
public void saveObject(Order Order) { Order.setOrder_id(UUID.randomUUID().toString()); mongoTemplate.insert(Order); }
Controller to handle requests
The controller
class has the customer repository and product repository references as per the use case. The application user needs to select the customer and product to place an order.
The initial Skelton of OrderController
is shown here:
@Controller public class OrderController { @Autowired private OrderRepository respository; @Autowired private CustomerRepository customerRespository; @Autowired private ProductRepository productRespository; private List<Order> orderList; private List<Customer> customerList; private List<Product> productList; public OrderController() { super(); } }
Adding the @Modelattribute annotation at the Method level
The
controller
class is to handle the
Order
requests. The @ModelAttribute
annotation is added to the method. The product list and customer list is always available as a model attribute to the controller. The following is the code snippet of the OrderController
class:
@ModelAttribute("orderList") public List<Order> populateOrderList() { this.orderList = respository.getAllObjects(); return this.orderList; } @ModelAttribute("productList") public List<Product> populateProductList() { this.productList = productRespository.getAllObjects(); return this.productList; } @ModelAttribute("customerList") public List<Customer> populateCstomerList() { this.customerList = customerRespository.getAllObjects(); return this.customerList; }
CRUD operations of the OrderController class
The methods are mapped to a particular request, @ModelAttribute("Order")
, to make the order object easily accessible at the JSP level. You can observe that using @ModelAttribute
at the method level; this will minimize adding @ModelAttribute
to the method.
@RequestMapping(value = "/order", method = RequestMethod.GET) // request show add order page public String addOrder(@ModelAttribute("Order") Order order,Map<String, Object> model) { model.put("customerList", customerList); model.put("productList", productList); return "order"; } @RequestMapping(value = "/order/save", method = RequestMethod.POST) // request to insert the record public String addorder(@ModelAttribute("Order") Order order,Map<String, Object> model) { order.setCustomer(customerRespository.getObject(order.getCustomer().getCust_id())); order.setProduct(product_respository.getObject(order.getProduct().getProdid())); respository.saveObject(order); model.put("customerList", customerList); model.put("productList", productList); return "order"; } @RequestMapping(value = "/orde`r/update", method = RequestMethod.POST) public String updatecustomer(@ModelAttribute("Order") Order order, Map<String, Object> model) { order.setCustomer(customerRespository.getObject(order.getCustomer().getCust_id())); order.setProduct(product_respository.getObject(order.getProduct().getProdid())); respository.updateObject(order); model.put("customerList", customerList); model.put("productList", productList); return "order"; } @RequestMapping(value = "/order/geteditorder", method = RequestMethod.GET) public String editOrder(@RequestParam(value = "order_id", required = true) String order_id, @ModelAttribute("Order") Order order,Map<String, Object> model) { model.put("customerList", customerList); model.put("productList", productList); model.put("Order",respository.getObject(order_id)); return "editorder"; } @RequestMapping(value = "/order/deleteorder", method = RequestMethod.GET) public String deleteorder(@RequestParam(value = "order_id", required = true) String order_id, @ModelAttribute("Order") Order order,Map<String, Object> model) { respository.deleteObject(order_id); model.put("customerList", customerList); model.put("productList", productList); return "order"; } }
JSP files
The Order.jsp
file demonstrates the use of @ModelAttribute
, which gets mapped to the Model Order defined in the controller class. The setter methods set the values to the objects, which minimizes the coding. This showcases a feature in spring, which simplifies the coding process.
Orders.jsp
<h1>Orders </h1> <ul> <li><a href="/Spring4MongoDB_Chapter1/customer">Customer</a> </li> <li>r<a href="/Spring4MongoDB_Chapter1/product">Product</a> </li></ul> <form:form action="/Spring4MongoDB_Chapter1/order/save" modelAttribute="Order"> <table> <tr> <td>Add your Order:</td> <td><form:input path="quantity" size="3"/></td> </tr> <tr> <td>Select Product:</td> <td> <form:select path="product.prodid"> <form:option value="" label="--Please Select"/> <form:options items="${productList}" itemValue="prodid" itemLabel="name"/> </form:select> </td> </tr> <tr> <td>Select Customer:</td> <td> <form:select path="customer.cust_id"> <form:option value="" label="--Please Select"/> <form:options items="${customerList}" itemValue="cust_id" itemLabel="name"/> </form:select> </td> </tr> <tr> <td colspan="2" align="center"> <input type="submit" value="Submit" /> </td> </tr> </table> </form:form> <%@ include file="allorders.jsp" %> </body> </html>
The allorders.jsp
file displays the list of orders with an option to edit. Use of MongoDB has made displaying the orderList
simpler.
Allorders.jsp
<h1> E-shop Orders</h1> <table style="border: 1px solid; width: 500px; text-align:center"> <thead style="background:#fffcc"> <tr> <th>Order Id</th> <th>Customer Name</th> <th>Customer Address</th> <th>Product Address</th> <th>Product Price</th> <th>Product Quantity</th> <th colspan="2"></th> </tr> </thead> <tbody> <c:forEach items="${orderList}" var="order"> <c:url var="editUrl" value="/order/geteditorder?order_id=${order.order_id}" /> <c:url var="deleteUrl" value="/order/deleteorder?order_id=${order.order_id}" /> <c:url var="addUrl" value="/order/" /> <tr> <td><c:out value="${order.order_id}" /></td> <td><c:out value="${order.customer.name}" /></td> <td><c:out value="${order.customer.address}" /></td> <td><c:out value="${order.product.name}" /></td> <td><c:out value="${order.product.price}" /></td> <td><c:out value="${order.quantity}" /></td> <td><a href="${editUrl}">Edit</a></td> <td><a href="${deleteUrl}">Delete</a></td> <td><a href="${addUrl}">Add</a></td> </tr> </c:forEach> </tbody>
The following is a screenshot of the page to add your order:
The following is a screenshot of the page to edit your order: