본문 바로가기
Projects/청하-청년을 위한 커뮤니티 서비스

[청하] 34. 정책 찜하기 기능 - 유니크 제약조건 문제 해결

by Lpromotion 2024. 10. 23.

1. 문제 상황

처음 도메인 엔티티 코드를 작성할 때 policyId는 중복 허용을 해야하는데 유니크 제약조건을 잘못 설정하여 문제가 발생했다.

여러 사람이 동일한 정책을 찜하려 할 때 유니크 제약조건 위반으로 오류가 발생하는 이슈가 생겼다.

 

스프링부트 오류 로그

2024-08-07T13:53:21.051Z  WARN 1 --- [nio-8080-exec-6] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 1062, SQLState: 23000
2024-08-07T13:53:21.051Z ERROR 1 --- [nio-8080-exec-6] o.h.engine.jdbc.spi.SqlExceptionHelper   : Duplicate entry 'R2024080625806' for key 'favorite_policies.UK_toh9ytorg03oy7bbc9c69wd4a'
2024-08-07T13:53:21.057Z ERROR 1 --- [nio-8080-exec-6] c.e.w.exception.GlobalExceptionHandler   : Handler in CommonException Error Message = 서버에서 오류가 발생했습니다. 잠시 후 다시 시도해주세요.
  • `SQL Error: 1062`: MySQL의 중복 키 에러 코드
  • `Duplicate entry 'R2024080625806'`: 'R2024080625806' 값이 이미 존재하는데 중복 입력을 시도함.
  • `UK_toh9ytorg03oy7bbc9c69wd4a`: policy_id 컬럼에 설정된 유니크 제약조건 키 이름

동일한 정책을 다른 사용자가 찜하려 할 때 유니크 제약조건 위반으로 실패했다는 로그이다.

 

2. FavoritePolidy 도메인 엔티티 수정

수정 전

@Column(name = "policy_id", nullable = false, unique = true)
private String policyId;

 

수정 후

@Column(name = "policy_id", nullable = false) // unique 제거함 (디폴트: false)
private String policyId;

 

3. 데이터베이스 수정

JPA의 엔티티 수정만으로는 기존 데이터베이스 제약 조건이 수정하거나 삭제하지 않기 때문에 직접 데이터베이스에 접속하여 해당하는 유니크 제약 조건을 삭제했다.

 

3.1. 제약 조건 확인

SHOW INDEX FROM favorite_policies;
mysql> show INDEX from favorite_policies;
+-------------------+------------+------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table             | Non_unique | Key_name                     | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------------------+------------+------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| favorite_policies |          0 | PRIMARY                      |            1 | id          | A         |          29 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| favorite_policies |          0 | UK_toh9ytorg03oy7bbc9c69wd4a |            1 | policy_id   | A         |          29 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| favorite_policies |          1 | FKafotsl6qd6faejqbr7rb9arww  |            1 | user_id     | A         |           3 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
+-------------------+------------+------------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
  • `PRIMARY`: 기본키(id)에 대한 인덱스
  • `UK_toh9ytorg03oy7bbc9c69wd4a`: policy_id 컬럼의 유니크 제약조건 (Non_unique가 0이므로 중복을 허용하지 않음 → 동일한 policy_id를 여러 사용자가 저장할 수 없음)
  • `FKafotsl6qd6faejqbr7rb9arww`: user_id에 대한 외래키 인덱스 (Non_unique가 1이므로 중복 허용 → 한 사용자가 여러 정책을 찜할 수 있음)

 

3.2. 인덱스 삭제

ALTER TABLE favorite_policies DROP INDEX UK_toh9ytorg03oy7bbc9c69wd4a;

 

4. 결론

여러 사람이 하나의 정책을 중복으로 찜할 수 있도록 수정되었다.

자꾸 이런 잔 실수가 있어서 PR 올리기 전에 확인을 더 많이 해야할 듯 하다.ㅜ

반응형

댓글