스프링 부트 버전 마이그레이션으로 인한 하이버네이트 버전 마이그레이션으로 인한 트러블슈팅

appti·2024년 2월 22일
0

트러블슈팅

목록 보기
3/3

서론

기존 프로젝트는 스프링 부트 버전을 3.0.8을 사용하고 있었습니다.
여기서 스프링 버전을 6.1로 올리기 위해 스프링 부트 버전을 3.2.2로 올렸습니다.

문제 상황

버전 업데이트 이후 181개의 테스트가 실패했습니다.
실패 원인은 다음과 같습니다.

could not execute statement [Unique index or primary key violation: "PUBLIC.CONSTRAINT_INDEX_39 ON PUBLIC.USER_RELIABILITY(USER_ID NULLS FIRST) VALUES ( /* 2 */ CAST(826 AS BIGINT) )";

181개의 테스트 모두 동일하게 유니크 제약조건을 성립하지 못하고 있었다는 이유였습니다.

다만 의아했던 부분은, 현재 프로젝트는 인덱스, 제약 조건 등에 모두 별도로 의미 있는 네이밍 사용

PUBLIC.CONSTRAINT_INDEX_39는 사용하고 있었던 모든 네이밍과는 맞지 않았고, 특히 마지막 39라는 숫자가 자동으로 생성된 제약 조건인 것이 느껴졌습니다.

이를 통해 직접 생성하지 않은 제약 조건이라고 판단했고, 하이버네이트를 의심했습니다.

스프링 부트 3.2.2로 마이그레이션 이후 하이버네이트는 6.1.7 -> 6.4.1이 되었습니다.
그래서 하이버네이트의 마이그레이션 내역을 확인했습니다.

하이버네이트 6.2

원인은 하이버네이트 6.2 마이그레이션 내역에서 바로 찾을 수 있었습니다.

One-To-One 관계에서 유니크 제약조건이 추가된다는 내용이었습니다.

엔티티 One-To-One 관계

프로젝트에는 수 많은 One-To-One 관계를 가진 엔티티가 있습니다.

그 중 하나인 User-UserReliability입니다.

해당 엔티티 테스트에서는 비교적 생성이 쉬운 UserReliablity를 재활용 했습니다.
이로 인해 테스트 시 User와 UserReliability는 Many-To-One 관계가 되었습니다.

하이버네이트 6.1에서는 큰 상관이 없었지만, 하이버네이트 6.2부터 One-To-One 관계에 논리적인 문맥을 지키고자 제약 조건을 추가해서 문제가 발생한 것이었습니다.

픽스처로 생성하고 있었던 만큼, 픽스처와 관련된 모든 테스트가 실패해 181개가 실패한 것이었습니다.

해결 방법

하이버네이트 6.2 마이그레이션 내역에서 해결 방법이 언급되어 있습니다.

Often the association can also be remapped
using @ManyToOne + @UniqueConstraint instead.

@ManyToOne + @UniqueConstraint를 사용하여 연관관계를 다시 매핑할 수도 있습니다.

즉 One-To-One 관계에서 하이버네이트에서 생성한 유니크 제약조건을 지키지 못했다면, 애초부터 One-To-One이 아니니 엔티티 간의 관계 설정을 다시 하라는 내용이었습니다.

필요하면 연관관계를 다시 재설정하라는 내용을 보고 이 제약 조건을 회피할 수는 없다고 생각했습니다.

또한, 일대일 관계에서 테스트 픽스처가 다대일이라는 것은 의미가 맞지 않기 때문에 예상하지 못한 버그를 놓칠 수도 있다는 생각이 들었습니다.

결론

코드 수정

엔티티 간의 관계는 One-To-One이었지만 테스트 픽스처에서는 Many-To-One인 코드를 전부 수정했습니다.

주의 사항

  • 테스트 픽스처에서도 엔티티 간 연관관계에 신경써야 합니다.
  • 스프링 부트 버전 업데이트 시 여러 라이브러리의 변경 사항을 고려해야 합니다.
profile
안녕하세요

0개의 댓글