JPA로 user id를 UUID로 설정하는 경우가 종종 있습니다.
public class Users {
@Id
private UUID userId;
}
그리고 JPA로 findByUserId(); 메서드로 유저 정보를 검색 쿼리를 던지는 순간 우리는
조회에 실패하고 null 값을 리턴하는 것을 볼 수 있습니다.
한참을.. 삽질하다 원인을 찾았는데
먼저 Hibernate가 mysql에 설정한 데이터 타입을 보겠습니다.
binary(255)로 설정되어 있습니다. 그런데 우리가 생성한 UUID 값을 찍어보면 binary(16)인 것을 볼 수 있습니다.
이렇게 되면 Hibernate는 16짜리 binary를 날리는데 mysql은 255를 채워야 하는 경우가 발생합니다. 그럼 우리의 mysql은 빈 공간을 padding 데이터를 알아서 집어넣게 됩니다.....
즉, 빈 공간은 000000..... 00으로 채우게 됩니다. 그러니 우리가 열심히 uuid를 날려도 뒤에 padding 값까지 들어가 있는 mysql의 데이터와는 매칭이 될 리가 없는 것입니다.
결국 데이터가 다르기 때문에 select값이 나오지 않는 것입니다.
해결법.
물론 검색할 때 padding 값을 채워서 보내면 정상적으로 검색이 됩니다. 하지만.. 그것은 굉장히 위험한 방식입니다. mysql은 0을 채우지만 다른 데이터베이스는 다른 값을 채울 수도 있고 또 안 채울지도 모릅니다.
즉, mysql에 우리는 16짜리 binary를 저장한다고 알려줘야 합니다.
public class Users {
@Id
@Column(columnDefinition = "BINARY(16)")
private UUID userId;
}
직접 칼럼 값을 지정해주면 mysql에 저장할 때 Hibernate가 16으로 저장합니다. 그러면 이제 패딩 값을 저장하지 않으니 우리가 알고 있는 UUID 값으로 조회가 가능합니다.
reference
https://dev.mysql.com/doc/refman/8.0/en/binary-varbinary.html
https://jehuipark.github.io/java/my-sql-binary-reference
'IT 이야기 > Java' 카테고리의 다른 글
[JWT] Java Web Token (0) | 2021.11.02 |
---|---|
[JPA] Entity의 N:M 관계를 개발하면서 느낀 것 (0) | 2021.08.10 |
springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: JsonObject; (1) | 2021.08.08 |
[Bean] JAVA vs Spring (0) | 2021.07.27 |
JPA Default value 적용 - @DynamicInsert (0) | 2021.07.20 |
댓글