#33 tdd(order-service): add product - jpa
This commit is contained in:
@@ -21,6 +21,8 @@ repositories {
|
||||
dependencies {
|
||||
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||
implementation 'com.google.guava:guava:31.1-jre'
|
||||
|
||||
compileOnly 'org.projectlombok:lombok'
|
||||
runtimeOnly 'com.h2database:h2'
|
||||
annotationProcessor 'org.projectlombok:lombok'
|
||||
|
||||
@@ -1,12 +1,23 @@
|
||||
package com.example.productorderservice.product;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
@Entity
|
||||
@Table(name = "products")
|
||||
@Getter
|
||||
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
||||
class Product {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
private final String name;
|
||||
private final int price;
|
||||
private final DiscountPolicy discountPolicy;
|
||||
private String name;
|
||||
private int price;
|
||||
private DiscountPolicy discountPolicy;
|
||||
|
||||
public Product(String name, int price, DiscountPolicy discountPolicy) {
|
||||
Assert.hasText(name, "상품명은 필수입니다.");
|
||||
@@ -18,11 +29,4 @@ class Product {
|
||||
this.discountPolicy = discountPolicy;
|
||||
}
|
||||
|
||||
public void assignId(final Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
package com.example.productorderservice.product;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Repository
|
||||
class ProductRepository {
|
||||
private Map<Long, Product> persistence = new HashMap<>();
|
||||
private Long sequence = 0L;
|
||||
|
||||
public void save(final Product product) {
|
||||
product.assignId(++sequence);
|
||||
persistence.put(product.getId(), product);
|
||||
}
|
||||
interface ProductRepository extends JpaRepository<Product, Long> {
|
||||
// private Map<Long, Product> persistence = new HashMap<>();
|
||||
// private Long sequence = 0L;
|
||||
//
|
||||
// public void save(final Product product) {
|
||||
// product.assignId(++sequence);
|
||||
// persistence.put(product.getId(), product);
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.example.productorderservice.product;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
class ProductService {
|
||||
@@ -11,6 +12,7 @@ class ProductService {
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
public void addProduct(AddProductRequest request) {
|
||||
final Product product = new Product(request.name(), request.price(), request.discountPolicy());
|
||||
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
|
||||
spring.jpa.properties.hibernate.show_sql=true
|
||||
spring.jpa.properties.hibernate.format_sql=true
|
||||
@@ -2,17 +2,25 @@ package com.example.productorderservice;
|
||||
|
||||
import io.restassured.RestAssured;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.web.server.LocalServerPort;
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
public class ApiTest {
|
||||
|
||||
@Autowired
|
||||
private DatabaseCleanup databaseCleanup;
|
||||
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
RestAssured.port = port;
|
||||
if (RestAssured.port == RestAssured.UNDEFINED_PORT) {
|
||||
RestAssured.port = port;
|
||||
databaseCleanup.afterPropertiesSet();
|
||||
}
|
||||
databaseCleanup.execute();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.example.productorderservice;
|
||||
|
||||
import com.google.common.base.CaseFormat;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.metamodel.EntityType;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
public class DatabaseCleanup implements InitializingBean {
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
private List<String> tableNames;
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
final Set<EntityType<?>> entities = entityManager.getMetamodel().getEntities();
|
||||
tableNames = entities.stream()
|
||||
.filter(e -> isEntity(e) && hasTableAnnotation(e))
|
||||
.map(e -> {
|
||||
String tableName = e.getJavaType().getAnnotation(Table.class).name();
|
||||
return tableName.isBlank() ? CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, e.getName()) : tableName;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
final List<String> entityNames = entities.stream()
|
||||
.filter(e -> isEntity(e) && !hasTableAnnotation(e))
|
||||
.map(e -> CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, e.getName()))
|
||||
.toList();
|
||||
|
||||
tableNames.addAll(entityNames);
|
||||
}
|
||||
|
||||
private boolean isEntity(final EntityType<?> e) {
|
||||
return null != e.getJavaType().getAnnotation(Entity.class);
|
||||
}
|
||||
|
||||
private boolean hasTableAnnotation(final EntityType<?> e) {
|
||||
return null != e.getJavaType().getAnnotation(Table.class);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void execute() {
|
||||
entityManager.flush();
|
||||
entityManager.createNativeQuery("SET REFERENTIAL_INTEGRITY FALSE").executeUpdate();
|
||||
|
||||
for (final String tableName : tableNames) {
|
||||
entityManager.createNativeQuery("TRUNCATE TABLE " + tableName).executeUpdate();
|
||||
entityManager.createNativeQuery("ALTER TABLE " + tableName + " ALTER COLUMN ID RESTART WITH 1").executeUpdate();
|
||||
}
|
||||
|
||||
entityManager.createNativeQuery("SET REFERENTIAL_INTEGRITY TRUE").executeUpdate();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user