반응형
💋 인트로
테스트 코드를 작성하는 도중에, 아래와 같은 에러를 만났다.
@Test
public void deleteProductTest() {
RestAssured.given()
.when()
.delete("/admin/products/1")
.then()
.statusCode(HttpStatus.NO_CONTENT.value());
}
Product를 지우고 나서 204 No Content 상태코드를 받는 테스트 코드이다.
왜 발생한 에러지??
💋 문제 원인
DELETE /admin/products/1의 요청을 보내면, 아래 메서드가 실행된다.
@DeleteMapping("admin/products/{id}")
public ResponseEntity<Void> deleteProduct(@PathVariable long id) {
deleteService.deleteProductBy(id);
return ResponseEntity.noContent().build();
}
여기서 호출하고 있는 deleteProductBy 메서드는 아래의 코드다.
@Service
public class ProductDeleteService {
private final ProductDao productDao;
public ProductDeleteService(final ProductDao productDao) {
this.productDao = productDao;
}
@Transactional
public void deleteProductBy(long id) {
productDao.deleteById(id);
}
}
DAO 구현체를 타고 들어가면
@Override
public void deleteById(long id) {
String sql = "DELETE FROM product WHERE id = :id";
Map<String, Long> parameter = Collections.singletonMap("id", id);
namedParameterJdbcTemplate.update(sql, parameter);
}
그치만 한 가지 문제가 있다!
나의 테이블 스키마를 보면, 아래와 같이 되어있다.
DROP TABLE IF EXISTS cart;
DROP TABLE IF EXISTS product;
DROP TABLE IF EXISTS member;
CREATE TABLE PRODUCT
(
id BIGINT NOT NULL AUTO_INCREMENT,
name VARCHAR(20) NOT NULL,
img_url VARCHAR(255),
price INT NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE MEMBER
(
id BIGINT NOT NULL AUTO_INCREMENT,
email VARCHAR(100) NOT NULL,
password VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE CART
(
id BIGINT NOT NULL AUTO_INCREMENT,
member_id BIGINT NOT NULL,
product_id BIGINT NOT NULL,
FOREIGN KEY (member_id) REFERENCES MEMBER (id),
FOREIGN KEY (product_id) REFERENCES PRODUCT (id),
PRIMARY KEY (id)
);
내가 현재 지우려고 하는 Product 테이블은 Cart 테이블의 외래 키로 사용되고 있기 때문에 지울 수가 없다.
💋 해결 방법: CASCADE 옵션 사용
foreign key로 묶인 테이블의 레코드가 삭제될 때, 해당 레코드를 참조하는 다른 테이블의 레코드도 함께 자동으로 삭제된다.
foreign key 제약 조건을 설정할 때 ON DELETE CASCADE 옵션을 추가하면 된다.
CREATE TABLE CART
(
id BIGINT NOT NULL AUTO_INCREMENT,
member_id BIGINT NOT NULL,
product_id BIGINT NOT NULL,
FOREIGN KEY (member_id) REFERENCES MEMBER (id) ON DELETE CASCADE,
FOREIGN KEY (product_id) REFERENCES PRODUCT (id) ON DELETE CASCADE,
PRIMARY KEY (id)
);
이렇게 변경하니!
편-안
끗
반응형
'MySQL' 카테고리의 다른 글
[MySQL] MVCC와 언두 로그(Undo log) (0) | 2023.08.29 |
---|---|
[MySQL] MySQL 엔진의 락 (Lock) (0) | 2023.08.15 |
[MySQL] MySQL 아키텍처: 접속 클라이언트, MySQL 엔진, 스토리지 엔진, 운영 체제, 하드웨어 (0) | 2023.08.14 |
[MySQL] 트랜잭션: 트랜잭션의 개념, 주의사항, 트랜잭션 VS 락 (Real MySQL 8.0) (0) | 2023.08.13 |
[MySQL] No value supplied for the SQL parameter 'gameId': No value registered for key 'gameId’ 오류 해결 (0) | 2023.04.28 |