UUID 主键未按预期映射到标准 existsById Jpa

UUID Primary Key not mapped as expected with standard existsById Jpa

我正在尝试引入 UUID 作为实体的主键,BINARY(16) 是其在 mysql 数据库中的表示形式。

我所拥有的是例如 UserId 是 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);

但是请注意,在 existsByUserId 中我必须添加 bin_to_uuid(:id) 而不是直接比较。我不太明白为什么我必须这样做,我通过直接查看数据库中的查询找到了这个解决方法并想出了这个。更新查询不添加 bin_to_uuid 而 select 计数。标准的 existsById 实现也不适用于 UUID ..

我有关于此的附加代码:

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);
    }
}

我不明白这两个查询之间的区别。但是在 DEBUG 模式下日志中的查询是:

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]

mysql 常规日志显示如下:

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')

如果有人能指出我对此的解释或展示更好的方法,我将不胜感激。谢谢!

对于后代来说,事实证明,列变换器的读取部分绝对是多余的,并且会产生上述问题。 JPA 绝对能够将 uuid 正确显示为字符串。所以你只需要用 write 属性:

创建 columntransformer
@ColumnTransformer(write="uuid_to_bin(?)")