본문 바로가기
IT 이야기/Java

[JPA] UUID로 findBy 조회가 안되는 이유

by Dblog 2021. 8. 15.
728x90

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

 

 

 

728x90

댓글