Reputation: 434
I am trying to introduce UUID as primary key for an entity with BINARY(16) being its representation in mysql database.
What I have is for example UserId being UUID:
//the column definition in the Entity
@Id
@Column(name="user_id", columnDefinition = "BINARY(16)")
@ColumnTransformer(
read="bin_to_uuid(user_id)",
write="uuid_to_bin(?)")
private UUID userId;
//repository methods
@Transactional
@Modifying
@Query("UPDATE User u SET u.status = :status WHERE u.userId= :id ")
int updateUserStatus(@Param("id") UUID id, @Param("status") UserStatus status);
@Query("SELECT count(u) from User u WHERE u.userId= bin_to_uuid(:id)")
int existsByUserId(@Param("id") UUID id);
However notice here that in existsByUserId I have to add bin_to_uuid(:id) instead of direct comparison. I dont quite understand why I have to do this, I found this workaround by looking at queries in DB directly and came up with this. The query for update doesnt add the bin_to_uuid whereas select count does. The standard existsById implementation also doesnt work with UUID ..
Additional code I have around this:
public void updateUserStatus(UUID id, int status) throws UserNotFoundException {
int rowsUpdated = userRepository.updateUserStatus(id, UserStatus.values()[status]);
if (rowsUpdated == 0) {
throw new UserNotFoundException(id);
}
}
public List<User> getFollowedBloggersByUser(UUID id, Pageable p) throws UserNotFoundException {
if (userRepository.existsByUserId(id) == 0) {
throw new UserNotFoundException(id);
} else {
return userFollowRepository.findByFollowerId(id,p);
}
}
I do not understand the difference between these two queries. But queries in the log in DEBUG mode are:
update users set status=? where user_id=?
binding parameter [1] as [INTEGER] - [1]
binding parameter [2] as [BINARY] - [420090c1-1a28-11eb-b98e-00155d2849a9]
select count(1) as col_0_0_ from users user0_ where bin_to_uuid(user0_.user_id)=bin_to_uuid(?)
binding parameter [1] as [BINARY] - [9e9eeb09-6a6d-405d-abd6-802c9c2c811d]
The mysql general log shows following:
update users set status=1 where user_id=x'420090C11A2811EBB98E00155D2849A9'
select count(1) as col_0_0_ from users user0_ where bin_to_uuid(user0_.user_id)=bin_to_uuid(x'9E9EEB096A6D405DABD6802C9C2C811D')
I would really appreciate if someone can point me in explanation of this or show the better way to do this. Thanks!
Upvotes: 1
Views: 531
Reputation: 434
For future generations, it turned out that the read part of column transformer is absolutely redundant and creates problems described above. JPA was absolutely capable of displaying uuid as a string correctly. So you just need to create columntransformer only with write property:
@ColumnTransformer(write="uuid_to_bin(?)")
Upvotes: 1