JPA Entity Id 타입을 UUID로 지정 시 업데이트 실패 오류

xlwdn·2022년 11월 29일
0
post-custom-banner

문제 원인


entity의 PK type을 kotlin 코드에서 UUID로 지정하고, jpa generate ddl 옵션을 허용하여 Spring Data JPA가 테이블을 생성하게 하였습니다.

@Entity
class Record(
): TimeEntity() {

    @Id
    @Column(name = "id", nullable = false)
    val id: UUID = UUID.randomUUID()
		...
}

하지만 이 때, 심각한 오류가 발생합니다.

batch update returned unexpected row count from update

위 오류 메시지는 해당 Record Entity를 수정하고 transactional 어노테이션이 종료되었을 때 발생한 내용입니다.

정확한 발생 상황은 entity를 save한 뒤, 나머지 로직을 거쳐서 성공 시 entity의 상태를 변경하는 코드를 실행했을 때 입니다.

@Trsanactional
fun exampleFun {
				val record = recordRepository.save(Record())
        try {
             //Business Logic
        } catch (e: Exception) {
            record.fail()
            throw BusinessException(e.message, ErrorCode.BAD_GATEWAY)
        }
        record.complete()
}

위와 같이 설정 시 Record를 저장할 때는 UUID값을 저장하므로 추후에 조회 시에도 “550e8400-e29b-41d4-a716-446655440000”과 같은 형태로 조회합니다.

하지만, 실제 DB에는 UUID (아무런 설정도 하지 않았을 때)타입이 없기에 타입이 변하게 되는데, 이때 binary(255)로 지정하게 됩니다.

위 사진은 실제 DB에 들어간 값인데요, 실제로 까보면

0xAD64672152AF405ABA041EA50805F1460000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

이렇게 저장되어 있습니다. 이러니 변경감지를 한 jpa가 update record set … where id = {id} 쿼리문을 실행하여 성공한 row 개수와 expected된 값인 불일치하였고, 때문에 해당 에러가 발생한 것입니다.

해결 방법


@Id
@Column(name = "id", nullable = false)
val id: String = UUID.randomUUID().toString()

Id칼럼 타입을 바꾸거나, Db를 drop하고 Column annotation, 또는 Id의 타입을 바꾸면 됩니다.

저는 테스트 중이었기에 DB를 drop하고 kotlin에서 Id의 타입을 바꿨습니다.

스크린샷 2022-11-12 오후 6.41.37.png

잘 되네요 🙂

post-custom-banner

0개의 댓글