You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot JPA使用UUID从MySQL查询记录返回null问题

问题:MySQL中UUID作为实体ID,JPA按ID查询返回null(数据库存在对应记录)

在MySQL数据库中使用UUID作为实体主键,通过JPA的findById方法查询时始终返回null,但通过Workbench确认数据库中确实存在该ID对应的记录。尝试将UUID以VARCHAR类型存储后问题仍未解决。

相关代码如下:

初始BaseEntity

@Getter(AccessLevel.PUBLIC)
@MappedSuperclass
public abstract class BaseEntity {
    @Id()
    @GeneratedValue(strategy = GenerationType.UUID)
    UUID id;

    @CreationTimestamp
    Date createdAt;
}

ArticlesRepository

@Repository
public interface ArticlesRepository extends JpaRepository<ArticleEntity, UUID> {
    ArticleEntity findBySlug(String slug);
    Optional<ArticleEntity> findById(UUID id);
}

ArticlesService

@Service
public class ArticlesService {

    public final ArticlesRepository articlesRepository;
    public final UsersRepository usersRepository;

    public ArticlesService(
            ArticlesRepository articlesRepository,
            UsersRepository usersRepository
    ) {
        this.articlesRepository = articlesRepository;
        this.usersRepository = usersRepository;
    }

    public List<ArticleEntity> getAllArticles(){
        List<ArticleEntity> articlesIterable = articlesRepository.findAll();
        return StreamSupport.stream(articlesIterable.spliterator(),false)
                .collect(Collectors.toList());
    }

    public ArticleEntity getArticleBySlug(String slug){
        var article = articlesRepository.findBySlug(slug);
        if(slug==null){
            return null;
        }
        return article;
    }

    public ArticleEntity createArticle(CreateArticleDTO createArticleDTO, String authorUsername){
        var author = usersRepository.findByUsername(authorUsername);
        return articlesRepository.save(
                ArticleEntity.builder()
                        .title(createArticleDTO.getTitle())
                        .slug(createArticleDTO.getTitle().toLowerCase().replaceAll(" ","-"))
                        .subtitle(createArticleDTO.getSubtitle())
                        .body(createArticleDTO.getBody())
                        .author(author)
                        .build()
                );
    }

    public Optional<ArticleEntity> getArticleById(UUID id){
        return articlesRepository.findById(id);
    }
}

尝试修改后的BaseEntity(无效)

public abstract class BaseEntity {
    @Id()
    @GeneratedValue(strategy = GenerationType.UUID)
    @JdbcTypeCode(SqlTypes.BINARY)
    UUID id;

    @CreationTimestamp
    Date createdAt;
}

解决方案

1. 对齐数据库字段类型与JPA映射

MySQL存储UUID推荐用CHAR(36)(UUID字符串固定36位含连字符),同时明确JPA字段映射:

@Id
@GeneratedValue(strategy = GenerationType.UUID)
@Column(columnDefinition = "CHAR(36)")
private UUID id;

2. 统一UUID大小写格式

若数据库字段使用区分大小写的排序规则(如utf8mb4_bin),需确保JPA生成的UUID与数据库存储的大小写一致:

  • 存储时强制转小写/大写
  • 查询时校验传入UUID的格式匹配数据库存储值

3. 校验UUID生成与存储格式一致性

检查GenerationType.UUID生成的UUID是否带连字符,若数据库存储的是无连字符的32位字符串,会导致匹配失败。手动打印生成的UUID和数据库中的值对比,确保格式完全一致。

4. 避免不必要的二进制存储

@JdbcTypeCode(SqlTypes.BINARY)会将UUID转为二进制字节数组存储,若未配置正确的类型转换器,极易导致查询匹配失败。非特殊需求建议直接用字符串存储UUID。

5. 清除EntityManager缓存

若之前查询过该ID返回null,一级缓存可能留存错误结果,可调用entityManager.clear()清除缓存后再查询,或使用findById的重载方法指定LockModeType.NONE绕过缓存。


内容的提问来源于stack exchange,提问作者Darth Plagueis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 13:13:13