• Home
  • About
    • Hanna's Blog photo

      Hanna's Blog

      I wanna be a global developer.

    • Learn More
    • Email
    • LinkedIn
    • Github
  • Posts
    • All Posts
    • All Tags
  • Projects

[Java Web Application] JPA Shop

15 Nov 2020

Reading time ~2 minutes

Reference by 실전! 스프링 부트와 JPA 활용 1 - 웹 애플리케이션 개발

Settings

  • Create project
    • Spring boot starter
    • dependencies : web, thymeleaf, jpa, h2, lombok, validation, devtools
    Spring boot Setting
  • Download lombok plugin

  • build.gradle
    • Add spring-boot-devtools(for recompile)
    • Add P6Spy
  • h2 database
    • Download
    • Go to h2/bin and excute h2-1.4.200.jar(os : window)
    • Connect DB
    H2 Databse Setting
  • Domain
    Domain Analyze
    • Connect DB
    H2 Databse Checking
    • @ManyToOne, @OneToMany
      Don’t use @ManyToMany. It cannot add colums in middle table.
      So create middle entity and mapping with @ManyToOne and @OneToMany.
  • Download Bootstrap

View

  • Thymeleaf Template Engine
    • Spring Boot thymeleaf View Name
      (resources:templates/) + {ViewName} + (.html)
    @Controller
    public class HelloController{

      @GetMapping("hello)
      public String hello(Model model){
        model.addAttribute("data", "hello!!");
        return "hello";
      }
    }
  
  • Template location
    resource/templates/hello.html
  • Skip null when use ?

Entity

  • fetch = FetchType.LAZY
    • EAGER is hard to expect and follow which SQL will excute.
    • To check related entities in DB together, use fetch, join or Entity Graph Function.
    • Need to set fetch = FetchType.LAZY in @OneToOne, @ManyToOne.

Application Architecture

Main
  • Hierarchy Structure
    • controller, web: web level
    • service: business logic, transaction process
    • repository: use JPA directly, use entity manager
    • domain: gather entities

Member

Repository

  • @Repository: Register as a spring bin
  • @PersistenceContext: Insert EntityManager
  • @PersistenceUnit: Insert EntityManagerFactory

Service

  • @Transactional: Transaction, perpetuity context
    • readOnly=true: Use for read-only methods
  • @Autowired: Use for many Generator Injection
    • If there is only one Generator, it can be skipped
  • final: Use to check error unsetted ~Repository

Test

  • @RunWith(SpringRunner.class): Combinate Spring and test
  • @SpringBootTest: Excute Spring Boot first, then test
  • @Transactional: Support repeatable test
    • Rollback after the test
  • //Given, //When, //Then
  • Setting for Test Case
    • Run in isolated environment and initialize data at end
    • Use Memory DB
    • Add Setting file for Test test/resources/application.yml
    spring:
    logging.level:
      org.hibernate.SQL: debug
  

Item

Entity

  • addStock(): Increase stock quantity when modify wtock quantity or cancel order
  • removeStock(): Decrease stock quantity. When stock is lack, generate error.

Repository

  • save()
    • Execute persist() for new id
    • Excutee merge() for existed id

Order

Entity

  • createdOrder(): Create Order Entity
  • cancle(): Change order status to cancle

Repository

  • findAll(OrderSearch orderSearch): Create queries dynamically in search condition to check order entities

Service

  • order(): Create Order Entity
  • cancleOrder(): Request cancel to Order
  • findOrders(): Search Order Entity with OrderSearch condition

    Domain Model Pattern: Entity has business logic
    Transaction Script Pattern: Service has business logic

Test

  • Generate NotEnoughStockException when order exceeds stock quantity

OrderItem

Entity

  • createOrderItem(): Create OrderItem Entity and call item.removeStock(count) to decrease stock quantity as much as order
  • cancle(): Call getItem().addStock(count) to increase stock quantity as much as cancled order
  • getTotalPrice(): Return count * price

Controller

  • Save Model object to send View
  • Press Submit, then request url with POST method
    • After the change, redirect redirect:/~
    • Excute method
  • Press Modify, then request url with GET method
    • Execute updateItemForm() method and call itemService.findOne(itemId)
    • send result to View
  • Always use change detection when changing an entity.

UI

  • Main
    Main
  • Member
    Sign
  • Product
    Product
  • Order
    Order

Demo Video

  • Member
  • Product
  • Modify
  • Order
  • Cancle
  • Search orders

Download



WebJavaSpringJPA Share Tweet +1