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의 타입을 바꿨습니다.
잘 되네요 🙂