[트러블 슈팅] nct club project
2023. 10. 7. 16:44
728x90
1. 데이터 베이스 테이블에 여러 개의 레코드 삽입 시, 외래 키 시퀀스 중복 및 무결성 문제 해결
1) 문제 발생 상황 | 1. nct 멤버 insert SQL문에 두 개의 테이블에 삽입 시 마이바티스를 통한 다중 insert를 하려고 함. > 그러나, DataIntegrityViolationException 발생 |
<insert id="insertMemberInfo" statementType="STATEMENT">
<![CDATA[
INSERT INTO nctmembers (memberId, name, birthdate, nationality, position, mbti, image, regdate)
VALUES (NCTMEMBERS_SEQ.NEXTVAL, #{name}, #{birthdate}, #{nationality}, #{position}, #{mbti}, #{image}, SYSDATE);
<foreach collection="groupList" item="group" separator=";">
INSERT INTO nctgroups (groupId, groupName, memberRefId)
VALUES (NCTGROUPS_SEQ.NEXTVAL, #{group}, NCTMEMBERS_SEQ.CURRVAL)
</foreach>
]]>
</insert>
2) 문제 발생 원인 | 버전이 맞지 않아 다중 insert SQL문이 제대로 적용되지 않음. |
3) 원인 해결 방법 | insert문을 두개로 나눔. |
<!-- Insert member -->
<insert id="insertMember">
INSERT INTO nctmembers (memberId, name, birthdate, nationality, position, mbti, image, regdate)
VALUES (NCTMEMBERS_SEQ.NEXTVAL, #{name}, #{birthdate}, #{nationality}, #{position}, #{mbti}, #{image}, SYSDATE)
</insert>
<!-- Insert groups for member -->
<insert id="insertGroupsForMember">
<foreach collection="groupList" item="group" index="index" separator=",">
INSERT INTO nctgroups (groupId, groupName, memberRefId)
VALUES (NCTGROUPS_SEQ.NEXTVAL, #{group}, NCTMEMBERS_SEQ.CURRVAL)
</foreach>
</insert>
1) 문제 발생 상황 2 | nct 멤버 insert 삽입 SQL문에 두 개의 컬럼에 시퀀스 값을 넣어야 해서 value값에 시퀀스.nextval과 currval을 각각 넣었다. > 그러나, 지속적으로 DataIntegrityViolationException 혹은 DuplicateKeyException 발생 |
2) 문제 발생 원인2 | 1. 한 멤버는 여러 그룹에 소속될 수 있다. > 엔시티 그룹 테이블 생성 & 엔시티 멤버 테이블의 memberId를 외래키로 가져옴. 2. 그러므로 INSERT문을 쓸 때에 두 개의 테이블에 삽입을 해주어야 함. (INSERT INTO nctmembers & INSERT INTO nctgroups) 3. 이 때 memberId는 nctmembers 테이블에 넣은 값으로 가져오기 위해 SEQ.CURRVAL을 사용하는데 foreach구문을 돌면서 시퀀스.nextval은 계속 같은 값이 INSERT 되면서 문제가 생겼다. 데이터 무결성 제약조건에 위반되는 것. |
3) 원인 해결 방법2 | 1. foreach문(다중 insert문)을 groupName에만 적용시킨다. > A.* FROM ( <foreach collection...></foreach>)A 설정 활용 2. memberId는 시퀀스.currval을 사용해야 하는데, 이걸 쉽게 가져오기 위해서 useGeneratedKeys 키 설정을 활용해 쉽게 멤버아이디 값을 받아오도록 한다. > useGeneratedKeys="true" keyProperty="id" keyColumn="memberId" |
<!-- Insert member -->
<insert id="insertMember" useGeneratedKeys="true" keyProperty="id" keyColumn="memberId">
INSERT INTO nctmembers (memberId, name, birthdate, nationality, position, mbti, image, regdate)
VALUES (NCTMEMBERS_SEQ.NEXTVAL, #{name}, #{birthdate}, #{nationality}, #{position}, #{mbti}, #{image}, SYSDATE)
</insert>
<!-- Insert groups for member -->
<insert id = "insertGroupsForMember" parameterType = "java.util.List">
INSERT INTO nctgroups (groupId, memberRefId, groupName)
SELECT NCTGROUPS_SEQ.NEXTVAL, #{id}, A.* FROM (
<foreach collection = "groupList" item = "group" separator = "UNION ALL">
SELECT #{group}
FROM DUAL
</foreach>) A
</insert>
4) 적용 및 해결 여부 확인 |
적용했더니 foreach문은 정상적으로 딱 groupName에만 적용되었고, keyProperty id를 활용해 #{id} 로 간단하게 표현하니 오류 해결 |
5) 예방 방안 | 테이블 여러 개에서 외래키 시퀀스를 입력할 때에는 각별한 유의가 필요하다. 특히나 시퀀스는 절대 겹치지 않도록 만들어놓은 장치이기 때문에 이를 활용해서 반복적으로 입력할 때에는 그 반복으로 인해 중복이 생기지 않도록 해야 한다. |
728x90
'Project > nct club project' 카테고리의 다른 글
[자바스크립트] url에서 파라미터를 추출하는 신기한 함수...(?) (1) | 2023.10.07 |
---|---|
[오류] 테이블 참조오류 (1) | 2023.10.06 |
[오류] 서버 인코딩 오류 (0) | 2023.10.03 |
오류와의 싸움기 흙 흙 ㅠㅡㅠ (1) | 2023.09.20 |
[이미지 업로드 기능] 만들기 (0) | 2023.09.19 |