From 3213f2c2170ba45accce64418d4f690f8d4ebab0 Mon Sep 17 00:00:00 2001 From: Raja Kolli Date: Wed, 4 Oct 2023 14:21:18 +0000 Subject: [PATCH] feat: enable 1-n mapping with caching --- .../hibernatecache/entities/Customer.java | 13 ++- .../hibernatecache/entities/Order.java | 19 +++- .../hibernatecache/entities/OrderItem.java | 34 +++++- .../example/hibernatecache/mapper/Mapper.java | 51 +++++++++ .../model/request/OrderRequest.java | 6 + .../model/response/CustomerResponse.java | 11 ++ .../model/response/OrderItemResponse.java | 3 + .../model/response/OrderResponse.java | 6 + .../repositories/CustomerRepository.java | 2 + .../services/CustomerService.java | 44 +++++-- .../services/OrderItemService.java | 32 ++++-- .../hibernatecache/services/OrderService.java | 44 +++++-- .../web/controllers/CustomerController.java | 51 ++++++--- .../web/controllers/OrderController.java | 24 ++-- .../web/controllers/OrderItemController.java | 13 ++- .../migration/02-create_orders_table.xml | 57 +++++----- .../migration/03-create_order_items_table.xml | 57 +++++----- .../ApplicationIntegrationTest.java | 15 ++- .../services/OrderItemServiceTest.java | 30 +++-- .../services/OrderServiceTest.java | 36 ++++-- .../web/controllers/CustomerControllerIT.java | 28 ++++- .../controllers/CustomerControllerTest.java | 107 +++++++++++++----- .../web/controllers/OrderControllerIT.java | 38 +++++-- .../web/controllers/OrderControllerTest.java | 65 +++++++---- .../controllers/OrderItemControllerIT.java | 38 +++++-- .../controllers/OrderItemControllerTest.java | 51 +++++---- 26 files changed, 625 insertions(+), 250 deletions(-) create mode 100644 jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/mapper/Mapper.java create mode 100644 jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/model/request/OrderRequest.java create mode 100644 jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/model/response/CustomerResponse.java create mode 100644 jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/model/response/OrderItemResponse.java create mode 100644 jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/model/response/OrderResponse.java diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/entities/Customer.java b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/entities/Customer.java index bf1326246..6c51dccb8 100644 --- a/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/entities/Customer.java +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/entities/Customer.java @@ -1,13 +1,10 @@ package com.example.hibernatecache.entities; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.Table; +import jakarta.persistence.*; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotEmpty; +import java.util.ArrayList; +import java.util.List; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; @@ -37,4 +34,8 @@ public class Customer { @Email private String email; private String phone; + + @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, orphanRemoval = true) + @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) + private List orders = new ArrayList<>(); } diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/entities/Order.java b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/entities/Order.java index 0133ce113..927989a36 100644 --- a/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/entities/Order.java +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/entities/Order.java @@ -1,18 +1,25 @@ package com.example.hibernatecache.entities; +import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; import jakarta.persistence.Table; -import jakarta.validation.constraints.NotEmpty; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import org.hibernate.Hibernate; +import org.hibernate.annotations.Cache; +import org.hibernate.annotations.CacheConcurrencyStrategy; @Entity @Table(name = "orders") @@ -20,6 +27,7 @@ @Setter @NoArgsConstructor @AllArgsConstructor +@Cache(region = "orderCache", usage = CacheConcurrencyStrategy.READ_WRITE) public class Order { @Id @@ -27,9 +35,16 @@ public class Order { private Long id; @Column(nullable = false) - @NotEmpty(message = "Text cannot be empty") private String text; + @ManyToOne + @JoinColumn(name = "customer_id") + private Customer customer; + + @OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true) + @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) + private List orderItems = new ArrayList<>(); + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/entities/OrderItem.java b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/entities/OrderItem.java index 1b4d400ec..cc5f5e836 100644 --- a/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/entities/OrderItem.java +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/entities/OrderItem.java @@ -1,10 +1,13 @@ package com.example.hibernatecache.entities; +import jakarta.persistence.Cacheable; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; import jakarta.validation.constraints.NotEmpty; import java.util.Objects; @@ -12,7 +15,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import org.hibernate.Hibernate; +import org.hibernate.proxy.HibernateProxy; @Entity @Table(name = "order_items") @@ -20,6 +23,7 @@ @Setter @NoArgsConstructor @AllArgsConstructor +@Cacheable public class OrderItem { @Id @@ -30,16 +34,34 @@ public class OrderItem { @NotEmpty(message = "Text cannot be empty") private String text; + @ManyToOne + @JoinColumn(name = "order_id") + private Order order; + @Override - public boolean equals(Object o) { + public final boolean equals(Object o) { if (this == o) return true; - if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + if (o == null) return false; + Class oEffectiveClass = + o instanceof HibernateProxy + ? ((HibernateProxy) o).getHibernateLazyInitializer().getPersistentClass() + : o.getClass(); + Class thisEffectiveClass = + this instanceof HibernateProxy + ? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass() + : this.getClass(); + if (thisEffectiveClass != oEffectiveClass) return false; OrderItem orderItem = (OrderItem) o; - return id != null && Objects.equals(id, orderItem.id); + return getId() != null && Objects.equals(getId(), orderItem.getId()); } @Override - public int hashCode() { - return getClass().hashCode(); + public final int hashCode() { + return this instanceof HibernateProxy + ? ((HibernateProxy) this) + .getHibernateLazyInitializer() + .getPersistentClass() + .hashCode() + : getClass().hashCode(); } } diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/mapper/Mapper.java b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/mapper/Mapper.java new file mode 100644 index 000000000..23fcad493 --- /dev/null +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/mapper/Mapper.java @@ -0,0 +1,51 @@ +package com.example.hibernatecache.mapper; + +import com.example.hibernatecache.entities.Customer; +import com.example.hibernatecache.entities.Order; +import com.example.hibernatecache.entities.OrderItem; +import com.example.hibernatecache.model.request.OrderRequest; +import com.example.hibernatecache.model.response.CustomerResponse; +import com.example.hibernatecache.model.response.OrderItemResponse; +import com.example.hibernatecache.model.response.OrderResponse; +import java.util.List; +import org.mapstruct.IterableMapping; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValueCheckStrategy; + +@org.mapstruct.Mapper( + componentModel = "spring", + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) +public interface Mapper { + + @Mapping(source = "id", target = "customerId") + CustomerResponse mapToCustomerResponse(Customer customer); + + @IterableMapping(elementTargetType = CustomerResponse.class) + List mapToCustomerResponseList(List customerList); + + void updateCustomerWithRequest(Customer customerRequest, @MappingTarget Customer savedCustomer); + + @Mapping(target = "customerId", source = "customer.id") + @Mapping(source = "id", target = "orderId") + OrderResponse orderToOrderResponse(Order order); + + @IterableMapping(elementTargetType = OrderResponse.class) + List mapToOrderResponseList(List orderList); + + @Mapping(target = "orderItems", ignore = true) + @Mapping(target = "id", ignore = true) + @Mapping(target = "customer", ignore = true) + void updateOrderWithRequest(OrderRequest orderRequest, @MappingTarget Order savedOrder); + + @Mapping(source = "id", target = "orderItemId") + OrderItemResponse orderItemToOrderItemResponse(OrderItem orderItem); + + @IterableMapping(elementTargetType = OrderItemResponse.class) + List orderItemListToOrderItemResponseList(List list); + + @Mapping(target = "orderItems", ignore = true) + @Mapping(target = "id", ignore = true) + @Mapping(target = "customer.id", source = "customerId") + Order mapToOrder(OrderRequest orderRequest); +} diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/model/request/OrderRequest.java b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/model/request/OrderRequest.java new file mode 100644 index 000000000..cf89dfb34 --- /dev/null +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/model/request/OrderRequest.java @@ -0,0 +1,6 @@ +package com.example.hibernatecache.model.request; + +import jakarta.validation.constraints.NotEmpty; + +public record OrderRequest( + Long customerId, @NotEmpty(message = "Text cannot be empty") String text) {} diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/model/response/CustomerResponse.java b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/model/response/CustomerResponse.java new file mode 100644 index 000000000..5cadeb156 --- /dev/null +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/model/response/CustomerResponse.java @@ -0,0 +1,11 @@ +package com.example.hibernatecache.model.response; + +import java.util.List; + +public record CustomerResponse( + Long customerId, + String firstName, + String lastName, + String email, + String phone, + List orders) {} diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/model/response/OrderItemResponse.java b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/model/response/OrderItemResponse.java new file mode 100644 index 000000000..4f1527d1b --- /dev/null +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/model/response/OrderItemResponse.java @@ -0,0 +1,3 @@ +package com.example.hibernatecache.model.response; + +public record OrderItemResponse(Long orderItemId, String text) {} diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/model/response/OrderResponse.java b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/model/response/OrderResponse.java new file mode 100644 index 000000000..9753700cb --- /dev/null +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/model/response/OrderResponse.java @@ -0,0 +1,6 @@ +package com.example.hibernatecache.model.response; + +import java.util.List; + +public record OrderResponse( + Long customerId, Long orderId, String text, List orderItems) {} diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/repositories/CustomerRepository.java b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/repositories/CustomerRepository.java index cc2b97ea7..ff049b259 100644 --- a/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/repositories/CustomerRepository.java +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/repositories/CustomerRepository.java @@ -5,6 +5,7 @@ import com.example.hibernatecache.entities.Customer; import jakarta.persistence.QueryHint; import java.util.Optional; +import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.QueryHints; import org.springframework.transaction.annotation.Transactional; @@ -13,5 +14,6 @@ public interface CustomerRepository extends JpaRepository { @Transactional(readOnly = true) @QueryHints(@QueryHint(name = HINT_CACHEABLE, value = "true")) + @EntityGraph(attributePaths = "orders") Optional findByFirstName(String firstName); } diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/services/CustomerService.java b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/services/CustomerService.java index 38039768e..7172e118c 100644 --- a/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/services/CustomerService.java +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/services/CustomerService.java @@ -1,10 +1,14 @@ package com.example.hibernatecache.services; import com.example.hibernatecache.entities.Customer; +import com.example.hibernatecache.mapper.Mapper; +import com.example.hibernatecache.model.response.CustomerResponse; +import com.example.hibernatecache.model.response.PagedResult; import com.example.hibernatecache.repositories.CustomerRepository; import java.util.List; import java.util.Optional; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -14,24 +18,48 @@ public class CustomerService { private final CustomerRepository customerRepository; + private final Mapper mapper; - public List findAllCustomers() { - return customerRepository.findAll(); + public PagedResult findAllCustomers( + int pageNo, int pageSize, String sortBy, String sortDir) { + Sort sort = + sortDir.equalsIgnoreCase(Sort.Direction.ASC.name()) + ? Sort.by(sortBy).ascending() + : Sort.by(sortBy).descending(); + + // create Pageable instance + Pageable pageable = PageRequest.of(pageNo, pageSize, sort); + Page customersPage = customerRepository.findAll(pageable); + List customerResponses = + mapper.mapToCustomerResponseList(customersPage.getContent()); + PageImpl customerResponsePage = + new PageImpl<>(customerResponses, pageable, customersPage.getTotalElements()); + return new PagedResult<>(customerResponsePage); } - public Optional findCustomerById(Long id) { - return customerRepository.findById(id); + public Optional findCustomerById(Long id) { + return findById(id).map(mapper::mapToCustomerResponse); } - public Customer saveCustomer(Customer customer) { - return customerRepository.save(customer); + public CustomerResponse saveCustomer(Customer customer) { + Customer saved = customerRepository.save(customer); + return mapper.mapToCustomerResponse(saved); } public void deleteCustomerById(Long id) { customerRepository.deleteById(id); } - public Optional findCustomerByFirstName(String firstName) { - return customerRepository.findByFirstName(firstName); + public Optional findCustomerByFirstName(String firstName) { + return customerRepository.findByFirstName(firstName).map(mapper::mapToCustomerResponse); + } + + public Optional findById(Long id) { + return customerRepository.findById(id); + } + + public CustomerResponse updateCustomer(Customer customerRequest, Customer savedCustomer) { + mapper.updateCustomerWithRequest(customerRequest, savedCustomer); + return saveCustomer(savedCustomer); } } diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/services/OrderItemService.java b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/services/OrderItemService.java index 6bd395420..4d3e6a498 100644 --- a/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/services/OrderItemService.java +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/services/OrderItemService.java @@ -1,14 +1,14 @@ package com.example.hibernatecache.services; import com.example.hibernatecache.entities.OrderItem; +import com.example.hibernatecache.mapper.Mapper; +import com.example.hibernatecache.model.response.OrderItemResponse; import com.example.hibernatecache.model.response.PagedResult; import com.example.hibernatecache.repositories.OrderItemRepository; +import java.util.List; import java.util.Optional; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; +import org.springframework.data.domain.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -17,13 +17,15 @@ public class OrderItemService { private final OrderItemRepository orderItemRepository; + private final Mapper mapper; @Autowired - public OrderItemService(OrderItemRepository orderItemRepository) { + public OrderItemService(OrderItemRepository orderItemRepository, Mapper mapper) { this.orderItemRepository = orderItemRepository; + this.mapper = mapper; } - public PagedResult findAllOrderItems( + public PagedResult findAllOrderItems( int pageNo, int pageSize, String sortBy, String sortDir) { Sort sort = sortDir.equalsIgnoreCase(Sort.Direction.ASC.name()) @@ -33,19 +35,27 @@ public PagedResult findAllOrderItems( // create Pageable instance Pageable pageable = PageRequest.of(pageNo, pageSize, sort); Page orderItemsPage = orderItemRepository.findAll(pageable); + List orderItemResponses = + mapper.orderItemListToOrderItemResponseList(orderItemsPage.getContent()); - return new PagedResult<>(orderItemsPage); + return new PagedResult<>( + new PageImpl<>(orderItemResponses, pageable, orderItemsPage.getTotalElements())); } - public Optional findOrderItemById(Long id) { - return orderItemRepository.findById(id); + public Optional findOrderItemById(Long id) { + return findById(id).map(mapper::orderItemToOrderItemResponse); } - public OrderItem saveOrderItem(OrderItem orderItem) { - return orderItemRepository.save(orderItem); + public OrderItemResponse saveOrderItem(OrderItem orderItem) { + OrderItem saved = orderItemRepository.save(orderItem); + return mapper.orderItemToOrderItemResponse(saved); } public void deleteOrderItemById(Long id) { orderItemRepository.deleteById(id); } + + public Optional findById(Long id) { + return orderItemRepository.findById(id); + } } diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/services/OrderService.java b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/services/OrderService.java index 9925ea80f..c0ea3b89e 100644 --- a/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/services/OrderService.java +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/services/OrderService.java @@ -1,14 +1,15 @@ package com.example.hibernatecache.services; import com.example.hibernatecache.entities.Order; +import com.example.hibernatecache.mapper.Mapper; +import com.example.hibernatecache.model.request.OrderRequest; +import com.example.hibernatecache.model.response.OrderResponse; import com.example.hibernatecache.model.response.PagedResult; import com.example.hibernatecache.repositories.OrderRepository; +import java.util.List; import java.util.Optional; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; +import org.springframework.data.domain.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -17,13 +18,15 @@ public class OrderService { private final OrderRepository orderRepository; + private final Mapper mapper; @Autowired - public OrderService(OrderRepository orderRepository) { + public OrderService(OrderRepository orderRepository, Mapper mapper) { this.orderRepository = orderRepository; + this.mapper = mapper; } - public PagedResult findAllOrders( + public PagedResult findAllOrders( int pageNo, int pageSize, String sortBy, String sortDir) { Sort sort = sortDir.equalsIgnoreCase(Sort.Direction.ASC.name()) @@ -34,18 +37,37 @@ public PagedResult findAllOrders( Pageable pageable = PageRequest.of(pageNo, pageSize, sort); Page ordersPage = orderRepository.findAll(pageable); - return new PagedResult<>(ordersPage); + List orderResponses = mapper.mapToOrderResponseList(ordersPage.getContent()); + Page orderResponsePage = + new PageImpl<>(orderResponses, pageable, ordersPage.getTotalElements()); + return new PagedResult<>(orderResponsePage); } - public Optional findOrderById(Long id) { - return orderRepository.findById(id); + public Optional findOrderById(Long id) { + return findById(id).map(mapper::orderToOrderResponse); } - public Order saveOrder(Order order) { - return orderRepository.save(order); + public OrderResponse saveOrderRequest(OrderRequest orderRequest) { + + Order order = mapper.mapToOrder(orderRequest); + return saveOrder(order); + } + + private OrderResponse saveOrder(Order order) { + Order saved = orderRepository.save(order); + return mapper.orderToOrderResponse(saved); } public void deleteOrderById(Long id) { orderRepository.deleteById(id); } + + public Optional findById(Long id) { + return orderRepository.findById(id); + } + + public OrderResponse updateOrder(Order orderObj, OrderRequest orderRequest) { + mapper.updateOrderWithRequest(orderRequest, orderObj); + return saveOrder(orderObj); + } } diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/web/controllers/CustomerController.java b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/web/controllers/CustomerController.java index 781dba163..b88c2d154 100644 --- a/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/web/controllers/CustomerController.java +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/web/controllers/CustomerController.java @@ -1,8 +1,10 @@ package com.example.hibernatecache.web.controllers; import com.example.hibernatecache.entities.Customer; +import com.example.hibernatecache.model.response.CustomerResponse; +import com.example.hibernatecache.model.response.PagedResult; import com.example.hibernatecache.services.CustomerService; -import java.util.List; +import com.example.hibernatecache.utils.AppConstants; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -32,12 +34,32 @@ public CustomerController(CustomerService customerService) { } @GetMapping - public List getAllCustomers() { - return customerService.findAllCustomers(); + public PagedResult getAllCustomers( + @RequestParam( + value = "pageNo", + defaultValue = AppConstants.DEFAULT_PAGE_NUMBER, + required = false) + int pageNo, + @RequestParam( + value = "pageSize", + defaultValue = AppConstants.DEFAULT_PAGE_SIZE, + required = false) + int pageSize, + @RequestParam( + value = "sortBy", + defaultValue = AppConstants.DEFAULT_SORT_BY, + required = false) + String sortBy, + @RequestParam( + value = "sortDir", + defaultValue = AppConstants.DEFAULT_SORT_DIRECTION, + required = false) + String sortDir) { + return customerService.findAllCustomers(pageNo, pageSize, sortBy, sortDir); } @GetMapping("/{id}") - public ResponseEntity getCustomerById(@PathVariable Long id) { + public ResponseEntity getCustomerById(@PathVariable Long id) { return customerService .findCustomerById(id) .map(ResponseEntity::ok) @@ -45,7 +67,8 @@ public ResponseEntity getCustomerById(@PathVariable Long id) { } @GetMapping("/search") - public ResponseEntity searchCustomer(@RequestParam("firstName") String firstName) { + public ResponseEntity searchCustomer( + @RequestParam("firstName") String firstName) { return customerService .findCustomerByFirstName(firstName) .map(ResponseEntity::ok) @@ -54,25 +77,25 @@ public ResponseEntity searchCustomer(@RequestParam("firstName") String @PostMapping @ResponseStatus(HttpStatus.CREATED) - public Customer createCustomer(@RequestBody @Validated Customer customer) { + public CustomerResponse createCustomer(@RequestBody @Validated Customer customer) { return customerService.saveCustomer(customer); } @PutMapping("/{id}") - public ResponseEntity updateCustomer( - @PathVariable Long id, @RequestBody Customer customer) { + public ResponseEntity updateCustomer( + @PathVariable Long id, @RequestBody Customer customerRequest) { return customerService - .findCustomerById(id) + .findById(id) .map( - customerObj -> { - customer.setId(id); - return ResponseEntity.ok(customerService.saveCustomer(customer)); - }) + customerObj -> + ResponseEntity.ok( + customerService.updateCustomer( + customerRequest, customerObj))) .orElseGet(() -> ResponseEntity.notFound().build()); } @DeleteMapping("/{id}") - public ResponseEntity deleteCustomer(@PathVariable Long id) { + public ResponseEntity deleteCustomer(@PathVariable Long id) { return customerService .findCustomerById(id) .map( diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/web/controllers/OrderController.java b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/web/controllers/OrderController.java index 953cb9e06..07f2cf5ff 100644 --- a/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/web/controllers/OrderController.java +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/web/controllers/OrderController.java @@ -1,6 +1,7 @@ package com.example.hibernatecache.web.controllers; -import com.example.hibernatecache.entities.Order; +import com.example.hibernatecache.model.request.OrderRequest; +import com.example.hibernatecache.model.response.OrderResponse; import com.example.hibernatecache.model.response.PagedResult; import com.example.hibernatecache.services.OrderService; import com.example.hibernatecache.utils.AppConstants; @@ -33,7 +34,7 @@ public OrderController(OrderService orderService) { } @GetMapping - public PagedResult getAllOrders( + public PagedResult getAllOrders( @RequestParam( value = "pageNo", defaultValue = AppConstants.DEFAULT_PAGE_NUMBER, @@ -58,7 +59,7 @@ public PagedResult getAllOrders( } @GetMapping("/{id}") - public ResponseEntity getOrderById(@PathVariable Long id) { + public ResponseEntity getOrderById(@PathVariable Long id) { return orderService .findOrderById(id) .map(ResponseEntity::ok) @@ -67,24 +68,23 @@ public ResponseEntity getOrderById(@PathVariable Long id) { @PostMapping @ResponseStatus(HttpStatus.CREATED) - public Order createOrder(@RequestBody @Validated Order order) { - return orderService.saveOrder(order); + public OrderResponse createOrder(@RequestBody @Validated OrderRequest orderRequest) { + return orderService.saveOrderRequest(orderRequest); } @PutMapping("/{id}") - public ResponseEntity updateOrder(@PathVariable Long id, @RequestBody Order order) { + public ResponseEntity updateOrder( + @PathVariable Long id, @RequestBody OrderRequest orderRequest) { return orderService - .findOrderById(id) + .findById(id) .map( - orderObj -> { - order.setId(id); - return ResponseEntity.ok(orderService.saveOrder(order)); - }) + orderObj -> + ResponseEntity.ok(orderService.updateOrder(orderObj, orderRequest))) .orElseGet(() -> ResponseEntity.notFound().build()); } @DeleteMapping("/{id}") - public ResponseEntity deleteOrder(@PathVariable Long id) { + public ResponseEntity deleteOrder(@PathVariable Long id) { return orderService .findOrderById(id) .map( diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/web/controllers/OrderItemController.java b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/web/controllers/OrderItemController.java index f88bf021e..4659a19fa 100644 --- a/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/web/controllers/OrderItemController.java +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/main/java/com/example/hibernatecache/web/controllers/OrderItemController.java @@ -1,6 +1,7 @@ package com.example.hibernatecache.web.controllers; import com.example.hibernatecache.entities.OrderItem; +import com.example.hibernatecache.model.response.OrderItemResponse; import com.example.hibernatecache.model.response.PagedResult; import com.example.hibernatecache.services.OrderItemService; import com.example.hibernatecache.utils.AppConstants; @@ -33,7 +34,7 @@ public OrderItemController(OrderItemService orderItemService) { } @GetMapping - public PagedResult getAllOrderItems( + public PagedResult getAllOrderItems( @RequestParam( value = "pageNo", defaultValue = AppConstants.DEFAULT_PAGE_NUMBER, @@ -58,7 +59,7 @@ public PagedResult getAllOrderItems( } @GetMapping("/{id}") - public ResponseEntity getOrderItemById(@PathVariable Long id) { + public ResponseEntity getOrderItemById(@PathVariable Long id) { return orderItemService .findOrderItemById(id) .map(ResponseEntity::ok) @@ -67,15 +68,15 @@ public ResponseEntity getOrderItemById(@PathVariable Long id) { @PostMapping @ResponseStatus(HttpStatus.CREATED) - public OrderItem createOrderItem(@RequestBody @Validated OrderItem orderItem) { + public OrderItemResponse createOrderItem(@RequestBody @Validated OrderItem orderItem) { return orderItemService.saveOrderItem(orderItem); } @PutMapping("/{id}") - public ResponseEntity updateOrderItem( + public ResponseEntity updateOrderItem( @PathVariable Long id, @RequestBody OrderItem orderItem) { return orderItemService - .findOrderItemById(id) + .findById(id) .map( orderItemObj -> { orderItem.setId(id); @@ -85,7 +86,7 @@ public ResponseEntity updateOrderItem( } @DeleteMapping("/{id}") - public ResponseEntity deleteOrderItem(@PathVariable Long id) { + public ResponseEntity deleteOrderItem(@PathVariable Long id) { return orderItemService .findOrderItemById(id) .map( diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/main/resources/db/changelog/migration/02-create_orders_table.xml b/jpa/boot-hibernate2ndlevelcache-sample/src/main/resources/db/changelog/migration/02-create_orders_table.xml index 7ba192275..8a25e8042 100644 --- a/jpa/boot-hibernate2ndlevelcache-sample/src/main/resources/db/changelog/migration/02-create_orders_table.xml +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/main/resources/db/changelog/migration/02-create_orders_table.xml @@ -1,27 +1,30 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/main/resources/db/changelog/migration/03-create_order_items_table.xml b/jpa/boot-hibernate2ndlevelcache-sample/src/main/resources/db/changelog/migration/03-create_order_items_table.xml index 8757048b7..2479e5446 100644 --- a/jpa/boot-hibernate2ndlevelcache-sample/src/main/resources/db/changelog/migration/03-create_order_items_table.xml +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/main/resources/db/changelog/migration/03-create_order_items_table.xml @@ -1,27 +1,30 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/ApplicationIntegrationTest.java b/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/ApplicationIntegrationTest.java index 60d692325..33625534c 100644 --- a/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/ApplicationIntegrationTest.java +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/ApplicationIntegrationTest.java @@ -19,21 +19,22 @@ class ApplicationIntegrationTest extends AbstractIntegrationTest { @Test void contextLoads() throws Exception { - Customer request = + Customer customer = new Customer( null, "firstNameTest", "lastName test", "emailtest@junit.com", - "9876543211"); + "9876543211", + null); SQLStatementCountValidator.reset(); this.mockMvc .perform( post("/api/customers") .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(request))) + .content(objectMapper.writeValueAsString(customer))) .andExpect(status().isCreated()) - .andExpect(jsonPath("$.firstName", is(request.getFirstName()))); + .andExpect(jsonPath("$.firstName", is(customer.getFirstName()))); assertInsertCount(1); // For selecting next sequence value assertSelectCount(1); @@ -43,7 +44,11 @@ void contextLoads() throws Exception { .perform( get("/api/customers/search?firstName=firstNameTest") .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()); + .andExpect(status().isOk()) + .andExpect(jsonPath("$.firstName", is(customer.getFirstName()))) + .andExpect(jsonPath("$.lastName", is(customer.getLastName()))) + .andExpect(jsonPath("$.email", is(customer.getEmail()))) + .andExpect(jsonPath("$.phone", is(customer.getPhone()))); } assertSelectCount(1); } diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/services/OrderItemServiceTest.java b/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/services/OrderItemServiceTest.java index bd0a643d9..f3e47e6c5 100644 --- a/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/services/OrderItemServiceTest.java +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/services/OrderItemServiceTest.java @@ -7,6 +7,8 @@ import static org.mockito.BDDMockito.willDoNothing; import com.example.hibernatecache.entities.OrderItem; +import com.example.hibernatecache.mapper.Mapper; +import com.example.hibernatecache.model.response.OrderItemResponse; import com.example.hibernatecache.model.response.PagedResult; import com.example.hibernatecache.repositories.OrderItemRepository; import java.util.List; @@ -26,6 +28,7 @@ class OrderItemServiceTest { @Mock private OrderItemRepository orderItemRepository; + @Mock private Mapper mapper; @InjectMocks private OrderItemService orderItemService; @@ -35,9 +38,12 @@ void findAllOrderItems() { Pageable pageable = PageRequest.of(0, 10, Sort.by(Sort.Direction.ASC, "id")); Page orderItemPage = new PageImpl<>(List.of(getOrderItem())); given(orderItemRepository.findAll(pageable)).willReturn(orderItemPage); + given(mapper.orderItemListToOrderItemResponseList(List.of(getOrderItem()))) + .willReturn(List.of(getOrderItemResponse())); // when - PagedResult pagedResult = orderItemService.findAllOrderItems(0, 10, "id", "asc"); + PagedResult pagedResult = + orderItemService.findAllOrderItems(0, 10, "id", "asc"); // then assertThat(pagedResult).isNotNull(); @@ -55,25 +61,29 @@ void findAllOrderItems() { void findOrderItemById() { // given given(orderItemRepository.findById(1L)).willReturn(Optional.of(getOrderItem())); + given(mapper.orderItemToOrderItemResponse(getOrderItem())) + .willReturn(getOrderItemResponse()); // when - Optional optionalOrderItem = orderItemService.findOrderItemById(1L); + Optional optionalOrderItem = orderItemService.findOrderItemById(1L); // then assertThat(optionalOrderItem).isPresent(); - OrderItem orderItem = optionalOrderItem.get(); - assertThat(orderItem.getId()).isEqualTo(1L); - assertThat(orderItem.getText()).isEqualTo("junitTest"); + OrderItemResponse orderItem = optionalOrderItem.get(); + assertThat(orderItem.orderItemId()).isEqualTo(1L); + assertThat(orderItem.text()).isEqualTo("junitTest"); } @Test void saveOrderItem() { // given given(orderItemRepository.save(getOrderItem())).willReturn(getOrderItem()); + given(mapper.orderItemToOrderItemResponse(getOrderItem())) + .willReturn(getOrderItemResponse()); // when - OrderItem persistedOrderItem = orderItemService.saveOrderItem(getOrderItem()); + OrderItemResponse persistedOrderItem = orderItemService.saveOrderItem(getOrderItem()); // then assertThat(persistedOrderItem).isNotNull(); - assertThat(persistedOrderItem.getId()).isEqualTo(1L); - assertThat(persistedOrderItem.getText()).isEqualTo("junitTest"); + assertThat(persistedOrderItem.orderItemId()).isEqualTo(1L); + assertThat(persistedOrderItem.text()).isEqualTo("junitTest"); } @Test @@ -92,4 +102,8 @@ private OrderItem getOrderItem() { orderItem.setText("junitTest"); return orderItem; } + + private OrderItemResponse getOrderItemResponse() { + return new OrderItemResponse(1L, "junitTest"); + } } diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/services/OrderServiceTest.java b/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/services/OrderServiceTest.java index 14432ae35..9918b9fbe 100644 --- a/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/services/OrderServiceTest.java +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/services/OrderServiceTest.java @@ -7,8 +7,12 @@ import static org.mockito.BDDMockito.willDoNothing; import com.example.hibernatecache.entities.Order; +import com.example.hibernatecache.mapper.Mapper; +import com.example.hibernatecache.model.request.OrderRequest; +import com.example.hibernatecache.model.response.OrderResponse; import com.example.hibernatecache.model.response.PagedResult; import com.example.hibernatecache.repositories.OrderRepository; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import org.junit.jupiter.api.Test; @@ -26,6 +30,7 @@ class OrderServiceTest { @Mock private OrderRepository orderRepository; + @Mock private Mapper mapper; @InjectMocks private OrderService orderService; @@ -35,9 +40,11 @@ void findAllOrders() { Pageable pageable = PageRequest.of(0, 10, Sort.by(Sort.Direction.ASC, "id")); Page orderPage = new PageImpl<>(List.of(getOrder())); given(orderRepository.findAll(pageable)).willReturn(orderPage); + given(mapper.mapToOrderResponseList(List.of(getOrder()))) + .willReturn(List.of(getOrderResponse())); // when - PagedResult pagedResult = orderService.findAllOrders(0, 10, "id", "asc"); + PagedResult pagedResult = orderService.findAllOrders(0, 10, "id", "asc"); // then assertThat(pagedResult).isNotNull(); @@ -55,25 +62,34 @@ void findAllOrders() { void findOrderById() { // given given(orderRepository.findById(1L)).willReturn(Optional.of(getOrder())); + given(mapper.orderToOrderResponse(getOrder())).willReturn(getOrderResponse()); // when - Optional optionalOrder = orderService.findOrderById(1L); + Optional optionalOrder = orderService.findOrderById(1L); // then assertThat(optionalOrder).isPresent(); - Order order = optionalOrder.get(); - assertThat(order.getId()).isEqualTo(1L); - assertThat(order.getText()).isEqualTo("junitTest"); + OrderResponse order = optionalOrder.get(); + assertThat(order.orderId()).isEqualTo(1L); + assertThat(order.text()).isEqualTo("junitTest"); } @Test void saveOrder() { // given + given(mapper.mapToOrder(getOrderRequest())).willReturn(getOrder()); given(orderRepository.save(getOrder())).willReturn(getOrder()); + given(mapper.orderToOrderResponse(getOrder())).willReturn(getOrderResponse()); + // when - Order persistedOrder = orderService.saveOrder(getOrder()); + OrderResponse persistedOrder = orderService.saveOrderRequest(getOrderRequest()); // then assertThat(persistedOrder).isNotNull(); - assertThat(persistedOrder.getId()).isEqualTo(1L); - assertThat(persistedOrder.getText()).isEqualTo("junitTest"); + assertThat(persistedOrder.customerId()).isEqualTo(1L); + assertThat(persistedOrder.orderId()).isEqualTo(1L); + assertThat(persistedOrder.text()).isEqualTo("junitTest"); + } + + private OrderRequest getOrderRequest() { + return new OrderRequest(1L, "junitTest"); } @Test @@ -92,4 +108,8 @@ private Order getOrder() { order.setText("junitTest"); return order; } + + private OrderResponse getOrderResponse() { + return new OrderResponse(1L, 1L, "junitTest", new ArrayList<>()); + } } diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/web/controllers/CustomerControllerIT.java b/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/web/controllers/CustomerControllerIT.java index 81e94a5d3..677b11115 100644 --- a/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/web/controllers/CustomerControllerIT.java +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/web/controllers/CustomerControllerIT.java @@ -1,6 +1,7 @@ package com.example.hibernatecache.web.controllers; import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.Matchers.hasSize; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -13,6 +14,7 @@ import com.example.hibernatecache.common.AbstractIntegrationTest; import com.example.hibernatecache.entities.Customer; import com.example.hibernatecache.repositories.CustomerRepository; +import com.example.hibernatecache.repositories.OrderRepository; import java.util.ArrayList; import java.util.List; import org.junit.jupiter.api.BeforeEach; @@ -23,20 +25,25 @@ class CustomerControllerIT extends AbstractIntegrationTest { @Autowired private CustomerRepository customerRepository; + @Autowired private OrderRepository orderRepository; private List customerList = null; @BeforeEach void setUp() { + orderRepository.deleteAll(); customerRepository.deleteAll(); customerList = new ArrayList<>(); customerList.add( - new Customer(null, "firstName 1", "lastName 1", "email1@junit.com", "9876543211")); + new Customer( + null, "firstName 1", "lastName 1", "email1@junit.com", "9876543211", null)); customerList.add( - new Customer(null, "firstName 2", "lastName 2", "email2@junit.com", "9876543212")); + new Customer( + null, "firstName 2", "lastName 2", "email2@junit.com", "9876543212", null)); customerList.add( - new Customer(null, "firstName 3", "lastName 3", "email3@junit.com", "9876543213")); + new Customer( + null, "firstName 3", "lastName 3", "email3@junit.com", "9876543213", null)); customerList = customerRepository.saveAll(customerList); } @@ -45,7 +52,14 @@ void shouldFetchAllCustomers() throws Exception { this.mockMvc .perform(get("/api/customers")) .andExpect(status().isOk()) - .andExpect(jsonPath("$.size()", is(customerList.size()))); + .andExpect(jsonPath("$.data.size()", is(customerList.size()))) + .andExpect(jsonPath("$.totalElements", is(3))) + .andExpect(jsonPath("$.pageNumber", is(1))) + .andExpect(jsonPath("$.totalPages", is(1))) + .andExpect(jsonPath("$.isFirst", is(true))) + .andExpect(jsonPath("$.isLast", is(true))) + .andExpect(jsonPath("$.hasNext", is(false))) + .andExpect(jsonPath("$.hasPrevious", is(false))); } @Test @@ -65,13 +79,15 @@ void shouldFindCustomerById() throws Exception { @Test void shouldCreateNewCustomer() throws Exception { Customer customer = - new Customer(null, "firstName 4", "lastName 4", "email4@junit.com", "9876543213"); + new Customer( + null, "firstName 4", "lastName 4", "email4@junit.com", "9876543213", null); this.mockMvc .perform( post("/api/customers") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(customer))) .andExpect(status().isCreated()) + .andExpect(jsonPath("$.customerId", notNullValue())) .andExpect(jsonPath("$.firstName", is(customer.getFirstName()))) .andExpect(jsonPath("$.lastName", is(customer.getLastName()))) .andExpect(jsonPath("$.email", is(customer.getEmail()))) @@ -80,7 +96,7 @@ void shouldCreateNewCustomer() throws Exception { @Test void shouldReturn400WhenCreateNewCustomerWithoutText() throws Exception { - Customer customer = new Customer(null, null, null, null, null); + Customer customer = new Customer(null, null, null, null, null, null); this.mockMvc .perform( diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/web/controllers/CustomerControllerTest.java b/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/web/controllers/CustomerControllerTest.java index d4349130e..accf85882 100644 --- a/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/web/controllers/CustomerControllerTest.java +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/web/controllers/CustomerControllerTest.java @@ -16,16 +16,21 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import com.example.hibernatecache.entities.Customer; +import com.example.hibernatecache.model.response.CustomerResponse; +import com.example.hibernatecache.model.response.PagedResult; import com.example.hibernatecache.services.CustomerService; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.ArrayList; import java.util.List; import java.util.Optional; +import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; import org.springframework.http.MediaType; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; @@ -46,34 +51,64 @@ class CustomerControllerTest { void setUp() { this.customerList = new ArrayList<>(); this.customerList.add( - new Customer(1L, "firstName 1", "lastName 1", "email1@junit.com", "9876543211")); + new Customer( + 1L, "firstName 1", "lastName 1", "email1@junit.com", "9876543211", null)); this.customerList.add( - new Customer(2L, "firstName 2", "lastName 2", "email2@junit.com", "9876543212")); + new Customer( + 2L, "firstName 2", "lastName 2", "email2@junit.com", "9876543212", null)); this.customerList.add( - new Customer(3L, "firstName 3", "lastName 3", "email3@junit.com", "9876543213")); + new Customer( + 3L, "firstName 3", "lastName 3", "email3@junit.com", "9876543213", null)); } @Test void shouldFetchAllCustomers() throws Exception { - given(customerService.findAllCustomers()).willReturn(this.customerList); + List customerMappedList = getCustomerResponses(); + + Page page = new PageImpl<>(customerMappedList); + PagedResult customerPagedResult = new PagedResult<>(page); + given(customerService.findAllCustomers(0, 10, "id", "asc")).willReturn(customerPagedResult); this.mockMvc .perform(get("/api/customers")) .andExpect(status().isOk()) - .andExpect(jsonPath("$.size()", is(customerList.size()))); + .andExpect(jsonPath("$.data.size()", is(customerMappedList.size()))) + .andExpect(jsonPath("$.totalElements", is(3))) + .andExpect(jsonPath("$.pageNumber", is(1))) + .andExpect(jsonPath("$.totalPages", is(1))) + .andExpect(jsonPath("$.isFirst", is(true))) + .andExpect(jsonPath("$.isLast", is(true))) + .andExpect(jsonPath("$.hasNext", is(false))) + .andExpect(jsonPath("$.hasPrevious", is(false))); + } + + @NotNull + private static List getCustomerResponses() { + List customerMappedList = new ArrayList<>(); + customerMappedList.add( + new CustomerResponse( + 1L, "firstName 1", "lastName 1", "email1@junit.com", "9876543211", null)); + customerMappedList.add( + new CustomerResponse( + 2L, "firstName 2", "lastName 2", "email2@junit.com", "9876543212", null)); + customerMappedList.add( + new CustomerResponse( + 3L, "firstName 3", "lastName 3", "email3@junit.com", "9876543213", null)); + return customerMappedList; } @Test void shouldFindCustomerById() throws Exception { Long customerId = 1L; - Customer customer = - (new Customer(3L, "firstName 3", "lastName 3", "email3@junit.com", "9876543213")); + CustomerResponse customer = + (new CustomerResponse( + 3L, "firstName 3", "lastName 3", "email3@junit.com", "9876543213", null)); given(customerService.findCustomerById(customerId)).willReturn(Optional.of(customer)); this.mockMvc .perform(get("/api/customers/{id}", customerId)) .andExpect(status().isOk()) - .andExpect(jsonPath("$.firstName", is(customer.getFirstName()))); + .andExpect(jsonPath("$.firstName", is(customer.firstName()))); } @Test @@ -88,24 +123,23 @@ void shouldReturn404WhenFetchingNonExistingCustomer() throws Exception { @Test void shouldCreateNewCustomer() throws Exception { - given(customerService.saveCustomer(any(Customer.class))) - .willAnswer((invocation) -> invocation.getArgument(0)); - - Customer customer = - (new Customer(3L, "firstName 3", "lastName 3", "email3@junit.com", "9876543213")); + CustomerResponse customer = + new CustomerResponse( + 3L, "firstName 3", "lastName 3", "email3@junit.com", "9876543213", null); + given(customerService.saveCustomer(any(Customer.class))).willReturn(customer); this.mockMvc .perform( post("/api/customers") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(customer))) .andExpect(status().isCreated()) - .andExpect(jsonPath("$.id", notNullValue())) - .andExpect(jsonPath("$.firstName", is(customer.getFirstName()))); + .andExpect(jsonPath("$.customerId", notNullValue())) + .andExpect(jsonPath("$.firstName", is(customer.firstName()))); } @Test void shouldReturn400WhenCreateNewCustomerWithoutFirstName() throws Exception { - Customer customer = new Customer(null, null, null, null, "9876543213"); + Customer customer = new Customer(null, null, null, null, "9876543213", null); this.mockMvc .perform( @@ -134,18 +168,27 @@ void shouldUpdateCustomer() throws Exception { "firstName Updated", "lastName 3", "email3@junit.com", - "9876543213"); - given(customerService.findCustomerById(customerId)).willReturn(Optional.of(customer)); - given(customerService.saveCustomer(any(Customer.class))) - .willAnswer((invocation) -> invocation.getArgument(0)); + "9876543213", + null); + CustomerResponse customerResponse = + new CustomerResponse( + customerId, + "firstName Updated", + "lastName 3", + "email3@junit.com", + "9876543213", + null); + given(customerService.findById(customerId)).willReturn(Optional.of(customer)); + given(customerService.updateCustomer(any(Customer.class), any(Customer.class))) + .willReturn(customerResponse); this.mockMvc .perform( - put("/api/customers/{id}", customer.getId()) + put("/api/customers/{id}", customerId) .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(customer))) .andExpect(status().isOk()) - .andExpect(jsonPath("$.firstName", is(customer.getFirstName()))); + .andExpect(jsonPath("$.firstName", is(customerResponse.firstName()))); } @Test @@ -153,7 +196,8 @@ void shouldReturn404WhenUpdatingNonExistingCustomer() throws Exception { Long customerId = 1L; given(customerService.findCustomerById(customerId)).willReturn(Optional.empty()); Customer customer = - new Customer(3L, "firstName 3", "lastName 3", "email3@junit.com", "9876543213"); + new Customer( + 3L, "firstName 3", "lastName 3", "email3@junit.com", "9876543213", null); this.mockMvc .perform( @@ -166,16 +210,21 @@ void shouldReturn404WhenUpdatingNonExistingCustomer() throws Exception { @Test void shouldDeleteCustomer() throws Exception { Long customerId = 1L; - Customer customer = - new Customer( - customerId, "firstName 3", "lastName 3", "email3@junit.com", "9876543213"); + CustomerResponse customer = + new CustomerResponse( + customerId, + "firstName 3", + "lastName 3", + "email3@junit.com", + "9876543213", + null); given(customerService.findCustomerById(customerId)).willReturn(Optional.of(customer)); - doNothing().when(customerService).deleteCustomerById(customer.getId()); + doNothing().when(customerService).deleteCustomerById(customerId); this.mockMvc - .perform(delete("/api/customers/{id}", customer.getId())) + .perform(delete("/api/customers/{id}", customerId)) .andExpect(status().isOk()) - .andExpect(jsonPath("$.firstName", is(customer.getFirstName()))); + .andExpect(jsonPath("$.firstName", is(customer.firstName()))); } @Test diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/web/controllers/OrderControllerIT.java b/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/web/controllers/OrderControllerIT.java index fae08469f..6a60f983f 100644 --- a/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/web/controllers/OrderControllerIT.java +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/web/controllers/OrderControllerIT.java @@ -12,7 +12,10 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import com.example.hibernatecache.common.AbstractIntegrationTest; +import com.example.hibernatecache.entities.Customer; import com.example.hibernatecache.entities.Order; +import com.example.hibernatecache.model.request.OrderRequest; +import com.example.hibernatecache.repositories.CustomerRepository; import com.example.hibernatecache.repositories.OrderRepository; import java.util.ArrayList; import java.util.List; @@ -24,17 +27,30 @@ class OrderControllerIT extends AbstractIntegrationTest { @Autowired private OrderRepository orderRepository; + @Autowired private CustomerRepository customerRepository; private List orderList = null; + private Customer savedCustomer; + @BeforeEach void setUp() { orderRepository.deleteAllInBatch(); - + customerRepository.deleteAll(); + + savedCustomer = + customerRepository.save( + new Customer( + null, + "firstName 1", + "lastName 1", + "email1@junit.com", + "9876543211", + null)); orderList = new ArrayList<>(); - orderList.add(new Order(null, "First Order")); - orderList.add(new Order(null, "Second Order")); - orderList.add(new Order(null, "Third Order")); + orderList.add(new Order(null, "First Order", savedCustomer, null)); + orderList.add(new Order(null, "Second Order", savedCustomer, null)); + orderList.add(new Order(null, "Third Order", savedCustomer, null)); orderList = orderRepository.saveAll(orderList); } @@ -61,26 +77,26 @@ void shouldFindOrderById() throws Exception { this.mockMvc .perform(get("/api/orders/{id}", orderId)) .andExpect(status().isOk()) - .andExpect(jsonPath("$.id", is(order.getId()), Long.class)) + .andExpect(jsonPath("$.orderId", is(order.getId()), Long.class)) .andExpect(jsonPath("$.text", is(order.getText()))); } @Test void shouldCreateNewOrder() throws Exception { - Order order = new Order(null, "New Order"); + OrderRequest order = new OrderRequest(savedCustomer.getId(), "New Order"); this.mockMvc .perform( post("/api/orders") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(order))) .andExpect(status().isCreated()) - .andExpect(jsonPath("$.id", notNullValue())) - .andExpect(jsonPath("$.text", is(order.getText()))); + .andExpect(jsonPath("$.orderId", notNullValue())) + .andExpect(jsonPath("$.text", is(order.text()))); } @Test void shouldReturn400WhenCreateNewOrderWithoutText() throws Exception { - Order order = new Order(null, null); + Order order = new Order(null, null, null, null); this.mockMvc .perform( @@ -111,7 +127,7 @@ void shouldUpdateOrder() throws Exception { .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(order))) .andExpect(status().isOk()) - .andExpect(jsonPath("$.id", is(order.getId()), Long.class)) + .andExpect(jsonPath("$.orderId", is(order.getId()), Long.class)) .andExpect(jsonPath("$.text", is(order.getText()))); } @@ -122,7 +138,7 @@ void shouldDeleteOrder() throws Exception { this.mockMvc .perform(delete("/api/orders/{id}", order.getId())) .andExpect(status().isOk()) - .andExpect(jsonPath("$.id", is(order.getId()), Long.class)) + .andExpect(jsonPath("$.orderId", is(order.getId()), Long.class)) .andExpect(jsonPath("$.text", is(order.getText()))); } } diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/web/controllers/OrderControllerTest.java b/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/web/controllers/OrderControllerTest.java index 9e2122eed..5246823e0 100644 --- a/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/web/controllers/OrderControllerTest.java +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/web/controllers/OrderControllerTest.java @@ -15,7 +15,10 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import com.example.hibernatecache.entities.Customer; import com.example.hibernatecache.entities.Order; +import com.example.hibernatecache.model.request.OrderRequest; +import com.example.hibernatecache.model.response.OrderResponse; import com.example.hibernatecache.model.response.PagedResult; import com.example.hibernatecache.services.OrderService; import com.fasterxml.jackson.databind.ObjectMapper; @@ -45,18 +48,26 @@ class OrderControllerTest { private List orderList; + Customer customer = + new Customer(1L, "firstName 1", "lastName 1", "email1@junit.com", "9876543211", null); + @BeforeEach void setUp() { this.orderList = new ArrayList<>(); - this.orderList.add(new Order(1L, "text 1")); - this.orderList.add(new Order(2L, "text 2")); - this.orderList.add(new Order(3L, "text 3")); + this.orderList.add(new Order(1L, "text 1", customer, null)); + this.orderList.add(new Order(2L, "text 2", customer, null)); + this.orderList.add(new Order(3L, "text 3", customer, null)); } @Test void shouldFetchAllOrders() throws Exception { - Page page = new PageImpl<>(orderList); - PagedResult orderPagedResult = new PagedResult<>(page); + List orderResponseList = + List.of( + new OrderResponse(1L, 1L, "text 1", new ArrayList<>()), + new OrderResponse(1L, 2L, "text 2", new ArrayList<>()), + new OrderResponse(1L, 3L, "text 3", new ArrayList<>())); + Page page = new PageImpl<>(orderResponseList); + PagedResult orderPagedResult = new PagedResult<>(page); given(orderService.findAllOrders(0, 10, "id", "asc")).willReturn(orderPagedResult); this.mockMvc @@ -75,13 +86,13 @@ void shouldFetchAllOrders() throws Exception { @Test void shouldFindOrderById() throws Exception { Long orderId = 1L; - Order order = new Order(orderId, "text 1"); + OrderResponse order = new OrderResponse(1L, orderId, "text 1", new ArrayList<>()); given(orderService.findOrderById(orderId)).willReturn(Optional.of(order)); this.mockMvc .perform(get("/api/orders/{id}", orderId)) .andExpect(status().isOk()) - .andExpect(jsonPath("$.text", is(order.getText()))); + .andExpect(jsonPath("$.text", is(order.text()))); } @Test @@ -94,23 +105,23 @@ void shouldReturn404WhenFetchingNonExistingOrder() throws Exception { @Test void shouldCreateNewOrder() throws Exception { - given(orderService.saveOrder(any(Order.class))) - .willAnswer((invocation) -> invocation.getArgument(0)); - Order order = new Order(1L, "some text"); + OrderRequest order = new OrderRequest(1L, "some text"); + OrderResponse orderResponse = new OrderResponse(1L, 1L, "some text", new ArrayList<>()); + given(orderService.saveOrderRequest(any(OrderRequest.class))).willReturn(orderResponse); this.mockMvc .perform( post("/api/orders") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(order))) .andExpect(status().isCreated()) - .andExpect(jsonPath("$.id", notNullValue())) - .andExpect(jsonPath("$.text", is(order.getText()))); + .andExpect(jsonPath("$.orderId", notNullValue())) + .andExpect(jsonPath("$.text", is(order.text()))); } @Test void shouldReturn400WhenCreateNewOrderWithoutText() throws Exception { - Order order = new Order(null, null); + Order order = new Order(null, null, null, null); this.mockMvc .perform( @@ -133,25 +144,28 @@ void shouldReturn400WhenCreateNewOrderWithoutText() throws Exception { @Test void shouldUpdateOrder() throws Exception { Long orderId = 1L; - Order order = new Order(orderId, "Updated text"); - given(orderService.findOrderById(orderId)).willReturn(Optional.of(order)); - given(orderService.saveOrder(any(Order.class))) - .willAnswer((invocation) -> invocation.getArgument(0)); + OrderRequest orderRequest = new OrderRequest(customer.getId(), "Updated text"); + Order order = new Order(orderId, "New text", customer, new ArrayList<>()); + given(orderService.findById(orderId)).willReturn(Optional.of(order)); + given(orderService.updateOrder(any(Order.class), any(OrderRequest.class))) + .willReturn( + new OrderResponse( + customer.getId(), orderId, "Updated text", new ArrayList<>())); this.mockMvc .perform( - put("/api/orders/{id}", order.getId()) + put("/api/orders/{id}", orderId) .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(order))) + .content(objectMapper.writeValueAsString(orderRequest))) .andExpect(status().isOk()) - .andExpect(jsonPath("$.text", is(order.getText()))); + .andExpect(jsonPath("$.text", is("Updated text"))); } @Test void shouldReturn404WhenUpdatingNonExistingOrder() throws Exception { Long orderId = 1L; given(orderService.findOrderById(orderId)).willReturn(Optional.empty()); - Order order = new Order(orderId, "Updated text"); + Order order = new Order(orderId, "Updated text", customer, null); this.mockMvc .perform( @@ -164,14 +178,15 @@ void shouldReturn404WhenUpdatingNonExistingOrder() throws Exception { @Test void shouldDeleteOrder() throws Exception { Long orderId = 1L; - Order order = new Order(orderId, "Some text"); + OrderResponse order = + new OrderResponse(customer.getId(), orderId, "Some text", new ArrayList<>()); given(orderService.findOrderById(orderId)).willReturn(Optional.of(order)); - doNothing().when(orderService).deleteOrderById(order.getId()); + doNothing().when(orderService).deleteOrderById(orderId); this.mockMvc - .perform(delete("/api/orders/{id}", order.getId())) + .perform(delete("/api/orders/{id}", orderId)) .andExpect(status().isOk()) - .andExpect(jsonPath("$.text", is(order.getText()))); + .andExpect(jsonPath("$.text", is(order.text()))); } @Test diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/web/controllers/OrderItemControllerIT.java b/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/web/controllers/OrderItemControllerIT.java index 2cd9df6e8..d3d00b188 100644 --- a/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/web/controllers/OrderItemControllerIT.java +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/web/controllers/OrderItemControllerIT.java @@ -12,8 +12,12 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import com.example.hibernatecache.common.AbstractIntegrationTest; +import com.example.hibernatecache.entities.Customer; +import com.example.hibernatecache.entities.Order; import com.example.hibernatecache.entities.OrderItem; +import com.example.hibernatecache.repositories.CustomerRepository; import com.example.hibernatecache.repositories.OrderItemRepository; +import com.example.hibernatecache.repositories.OrderRepository; import java.util.ArrayList; import java.util.List; import org.junit.jupiter.api.BeforeEach; @@ -24,17 +28,33 @@ class OrderItemControllerIT extends AbstractIntegrationTest { @Autowired private OrderItemRepository orderItemRepository; + @Autowired private OrderRepository orderRepository; + @Autowired private CustomerRepository customerRepository; private List orderItemList = null; + Order savedOrder; @BeforeEach void setUp() { orderItemRepository.deleteAllInBatch(); + orderRepository.deleteAllInBatch(); + customerRepository.deleteAllInBatch(); + + Customer savedCustomer = + customerRepository.save( + new Customer( + null, + "firstName 1", + "lastName 1", + "email1@junit.com", + "9876543211", + null)); + savedOrder = orderRepository.save(new Order(null, "First Order", savedCustomer, null)); orderItemList = new ArrayList<>(); - orderItemList.add(new OrderItem(null, "First OrderItem")); - orderItemList.add(new OrderItem(null, "Second OrderItem")); - orderItemList.add(new OrderItem(null, "Third OrderItem")); + orderItemList.add(new OrderItem(null, "First OrderItem", savedOrder)); + orderItemList.add(new OrderItem(null, "Second OrderItem", savedOrder)); + orderItemList.add(new OrderItem(null, "Third OrderItem", savedOrder)); orderItemList = orderItemRepository.saveAll(orderItemList); } @@ -61,26 +81,26 @@ void shouldFindOrderItemById() throws Exception { this.mockMvc .perform(get("/api/order/items/{id}", orderItemId)) .andExpect(status().isOk()) - .andExpect(jsonPath("$.id", is(orderItem.getId()), Long.class)) + .andExpect(jsonPath("$.orderItemId", is(orderItem.getId()), Long.class)) .andExpect(jsonPath("$.text", is(orderItem.getText()))); } @Test void shouldCreateNewOrderItem() throws Exception { - OrderItem orderItem = new OrderItem(null, "New OrderItem"); + OrderItem orderItem = new OrderItem(null, "New OrderItem", savedOrder); this.mockMvc .perform( post("/api/order/items") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(orderItem))) .andExpect(status().isCreated()) - .andExpect(jsonPath("$.id", notNullValue())) + .andExpect(jsonPath("$.orderItemId", notNullValue())) .andExpect(jsonPath("$.text", is(orderItem.getText()))); } @Test void shouldReturn400WhenCreateNewOrderItemWithoutText() throws Exception { - OrderItem orderItem = new OrderItem(null, null); + OrderItem orderItem = new OrderItem(null, null, savedOrder); this.mockMvc .perform( @@ -111,7 +131,7 @@ void shouldUpdateOrderItem() throws Exception { .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(orderItem))) .andExpect(status().isOk()) - .andExpect(jsonPath("$.id", is(orderItem.getId()), Long.class)) + .andExpect(jsonPath("$.orderItemId", is(orderItem.getId()), Long.class)) .andExpect(jsonPath("$.text", is(orderItem.getText()))); } @@ -122,7 +142,7 @@ void shouldDeleteOrderItem() throws Exception { this.mockMvc .perform(delete("/api/order/items/{id}", orderItem.getId())) .andExpect(status().isOk()) - .andExpect(jsonPath("$.id", is(orderItem.getId()), Long.class)) + .andExpect(jsonPath("$.orderItemId", is(orderItem.getId()), Long.class)) .andExpect(jsonPath("$.text", is(orderItem.getText()))); } } diff --git a/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/web/controllers/OrderItemControllerTest.java b/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/web/controllers/OrderItemControllerTest.java index 381ae4b1c..68f08da69 100644 --- a/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/web/controllers/OrderItemControllerTest.java +++ b/jpa/boot-hibernate2ndlevelcache-sample/src/test/java/com/example/hibernatecache/web/controllers/OrderItemControllerTest.java @@ -15,7 +15,10 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import com.example.hibernatecache.entities.Customer; +import com.example.hibernatecache.entities.Order; import com.example.hibernatecache.entities.OrderItem; +import com.example.hibernatecache.model.response.OrderItemResponse; import com.example.hibernatecache.model.response.PagedResult; import com.example.hibernatecache.services.OrderItemService; import com.fasterxml.jackson.databind.ObjectMapper; @@ -44,19 +47,29 @@ class OrderItemControllerTest { @Autowired private ObjectMapper objectMapper; private List orderItemList; + private Order savedOrder; @BeforeEach void setUp() { + Customer savedCustomer = + new Customer( + null, "firstName 1", "lastName 1", "email1@junit.com", "9876543211", null); + savedOrder = new Order(null, "First Order", savedCustomer, null); this.orderItemList = new ArrayList<>(); - this.orderItemList.add(new OrderItem(1L, "text 1")); - this.orderItemList.add(new OrderItem(2L, "text 2")); - this.orderItemList.add(new OrderItem(3L, "text 3")); + this.orderItemList.add(new OrderItem(1L, "text 1", savedOrder)); + this.orderItemList.add(new OrderItem(2L, "text 2", savedOrder)); + this.orderItemList.add(new OrderItem(3L, "text 3", savedOrder)); } @Test void shouldFetchAllOrderItems() throws Exception { - Page page = new PageImpl<>(orderItemList); - PagedResult orderItemPagedResult = new PagedResult<>(page); + List orderItemResponseList = + List.of( + new OrderItemResponse(1L, "text 1"), + new OrderItemResponse(2L, "text 2"), + new OrderItemResponse(3L, "text 3")); + Page page = new PageImpl<>(orderItemResponseList); + PagedResult orderItemPagedResult = new PagedResult<>(page); given(orderItemService.findAllOrderItems(0, 10, "id", "asc")) .willReturn(orderItemPagedResult); @@ -76,13 +89,13 @@ void shouldFetchAllOrderItems() throws Exception { @Test void shouldFindOrderItemById() throws Exception { Long orderItemId = 1L; - OrderItem orderItem = new OrderItem(orderItemId, "text 1"); + OrderItemResponse orderItem = new OrderItemResponse(orderItemId, "text 1"); given(orderItemService.findOrderItemById(orderItemId)).willReturn(Optional.of(orderItem)); this.mockMvc .perform(get("/api/order/items/{id}", orderItemId)) .andExpect(status().isOk()) - .andExpect(jsonPath("$.text", is(orderItem.getText()))); + .andExpect(jsonPath("$.text", is(orderItem.text()))); } @Test @@ -98,22 +111,22 @@ void shouldReturn404WhenFetchingNonExistingOrderItem() throws Exception { @Test void shouldCreateNewOrderItem() throws Exception { given(orderItemService.saveOrderItem(any(OrderItem.class))) - .willAnswer((invocation) -> invocation.getArgument(0)); + .willReturn(new OrderItemResponse(1L, "some text")); - OrderItem orderItem = new OrderItem(1L, "some text"); + OrderItem orderItem = new OrderItem(1L, "some text", savedOrder); this.mockMvc .perform( post("/api/order/items") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(orderItem))) .andExpect(status().isCreated()) - .andExpect(jsonPath("$.id", notNullValue())) + .andExpect(jsonPath("$.orderItemId", notNullValue())) .andExpect(jsonPath("$.text", is(orderItem.getText()))); } @Test void shouldReturn400WhenCreateNewOrderItemWithoutText() throws Exception { - OrderItem orderItem = new OrderItem(null, null); + OrderItem orderItem = new OrderItem(null, null, savedOrder); this.mockMvc .perform( @@ -136,10 +149,10 @@ void shouldReturn400WhenCreateNewOrderItemWithoutText() throws Exception { @Test void shouldUpdateOrderItem() throws Exception { Long orderItemId = 1L; - OrderItem orderItem = new OrderItem(orderItemId, "Updated text"); - given(orderItemService.findOrderItemById(orderItemId)).willReturn(Optional.of(orderItem)); + OrderItem orderItem = new OrderItem(orderItemId, "Updated text", savedOrder); + given(orderItemService.findById(orderItemId)).willReturn(Optional.of(orderItem)); given(orderItemService.saveOrderItem(any(OrderItem.class))) - .willAnswer((invocation) -> invocation.getArgument(0)); + .willReturn(new OrderItemResponse(orderItemId, "Updated text")); this.mockMvc .perform( @@ -154,7 +167,7 @@ void shouldUpdateOrderItem() throws Exception { void shouldReturn404WhenUpdatingNonExistingOrderItem() throws Exception { Long orderItemId = 1L; given(orderItemService.findOrderItemById(orderItemId)).willReturn(Optional.empty()); - OrderItem orderItem = new OrderItem(orderItemId, "Updated text"); + OrderItem orderItem = new OrderItem(orderItemId, "Updated text", savedOrder); this.mockMvc .perform( @@ -167,14 +180,14 @@ void shouldReturn404WhenUpdatingNonExistingOrderItem() throws Exception { @Test void shouldDeleteOrderItem() throws Exception { Long orderItemId = 1L; - OrderItem orderItem = new OrderItem(orderItemId, "Some text"); + OrderItemResponse orderItem = new OrderItemResponse(orderItemId, "Some text"); given(orderItemService.findOrderItemById(orderItemId)).willReturn(Optional.of(orderItem)); - doNothing().when(orderItemService).deleteOrderItemById(orderItem.getId()); + doNothing().when(orderItemService).deleteOrderItemById(orderItemId); this.mockMvc - .perform(delete("/api/order/items/{id}", orderItem.getId())) + .perform(delete("/api/order/items/{id}", orderItemId)) .andExpect(status().isOk()) - .andExpect(jsonPath("$.text", is(orderItem.getText()))); + .andExpect(jsonPath("$.text", is(orderItem.text()))); } @Test