인프런 커뮤니티 질문&답변

김지환님의 프로필 이미지

작성한 질문수

토비의 스프링 6 - 이해와 원리

DataAccessException과 예외 추상화

섹션5 - DataAccessException과 예외 추상화 질문 있습니다.

작성

·

223

·

수정됨

1

문제)

DataClient 에서 Hibernate 의 ConstraintViolationException 이 DataAccessException 으로 던져지지 않았습니다.

(발생한 예외 - 예상한 기댓값이 아님)

Exception in thread "main" org.hibernate.exception.ConstraintViolationException: could not execute statement [Unique index or primary key violation: "PUBLIC.UK43EGXXCIQR9NCGMXBDX2AVI8N_INDEX_8 ON PUBLIC.ORDERS(NO NULLS FIRST) VALUES ( /* 1 */ '100' )"; SQL statement:


원인)

Order Object 에서 @GeneratedValue 의 strategy 를 IDENTITY 로 작성해서 발생한 문제였습니다.

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

(변경된 예외 - 예상 기댓값으로 동작 성공)

Exception in thread "main" org.springframework.dao.DataIntegrityViolationException: could not execute statement [Unique index or primary key violation: "PUBLIC.UK43EGXXCIQR9NCGMXBDX2AVI8N_INDEX_8 ON PUBLIC.ORDERS(NO NULLS FIRST) VALUES ( /* 1 */ '100' )"; SQL statement:


질문사항)

안녕하세요 토비님. 위에 작성된 문제점을 발견했고 해결했음에도 JPA를 학습해보지 않아서 그런지.. 위 문제가 발생한 이유를 모르겠습니다.

  1. 대충 생각하기에는 IDENTITY strategy가 DB로 권한을 넘기기 때문에 EntityManager 의 영속성 컨텍스트에서 발생한 문제점이 아니라서 DataAccessException Layer에서 관리하지 못하는 것인가..? 라는 생각은 드는데 혹시 맞을까요?

  1. 비슷한 상황을 만들어보려고 IDENTITY strategy를 설정하지 않고 OrderRepository 에서 flush 를 해본 결과, 예상대로 ConstraintViolationException 가 뜨긴 하는데 ID가 null 이라서 DB에서 직접 접근 후 저장하는 작업을 한 번 해서 그럴까요?

답변 1

1

토비님의 프로필 이미지
토비
지식공유자

꽤 흥미로운 현상이네요. 저도 확인했습니다.
실무에선 H2 메모리 방식은 테스트 외에는 잘 사용하지 않았기 때문에 이런 경우는 처음 봅니다.

어쨌든 JPA 구현체인 하이버네이트의 ConstraintViolationException까지는 적용이 됐는데 스프링의 exception translation을 못 타고 있네요. 이게 디폴트인 sequence 방식 대신 identity를 썼기 때문이라고 보더라도, 결국 둘 다 insert가 실행되는 시점에 발행하는 예외인데 하나는 왜 변환이 안 되는지 저도 궁금하네요.

시간이 나면 H2의 서버 모드와 MySQL에서 IDENTITY 전략을 썼을 때 어떤지 한번 확인을 해보겠습니다.

다른 경우엔 다 문제가 없다면 스프링 버그 일지도요. 여유가 생기면 시간을 내서 찾아보겠습니다.

김지환님의 프로필 이미지
김지환
질문자

정확한 원인을 알지 못해서 아쉽지만, 토비님께서 흥미를 느낄만한 문제를 발견했다는 점만으로도 감개무량하네요.

좋은 강의를 제공해주시고 친절한 답변주셔서 감사합니다! 무더운 날 건강 조심하세요!