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

Spring Boot JPA复合主键实体findAll()返回空列表问题排查

解决JPA复合主键映射导致findAll()返回空的问题

问题出在你的实体类主键映射和数据库的复合主键不匹配——数据库表mm_enterprise是systemcode、lid、euid三个字段联合做主键,但你的EUID实体只把lid标为@Id。Hibernate虽然能生成正确的查询SQL,但在把结果封装成实体时,因为主键标识不对,没法正确关联数据,所以返回空列表。

不用改数据库表结构,按下面的步骤调整代码就能解决:

  • 创建复合主键类
    写一个实现Serializable的类,用@Embeddable注解标记,把三个主键字段都放进去,同时重写equals和hashCode方法(JPA要求主键类必须实现这两个方法)。

    import jakarta.persistence.Embeddable;
    import java.io.Serializable;
    import java.util.Objects;
    
    @Embeddable
    public class EnterprisePK implements Serializable {
        private String systemcode;
        private String lid;
        private String euid;
    
        // 必须有无参构造
        public EnterprisePK() {}
    
        // 全参构造方便使用
        public EnterprisePK(String systemcode, String lid, String euid) {
            this.systemcode = systemcode;
            this.lid = lid;
            this.euid = euid;
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            EnterprisePK that = (EnterprisePK) o;
            return Objects.equals(systemcode, that.systemcode) &&
                   Objects.equals(lid, that.lid) &&
                   Objects.equals(euid, that.euid);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(systemcode, lid, euid);
        }
    
        // 三个字段的getter、setter方法
        public String getSystemcode() { return systemcode; }
        public void setSystemcode(String systemcode) { this.systemcode = systemcode; }
        public String getLid() { return lid; }
        public void setLid(String lid) { this.lid = lid; }
        public String getEuid() { return euid; }
        public void setEuid(String euid) { this.euid = euid; }
    }
    
  • 修改EUID实体类
    把原来单独标记@Id的lid字段去掉,换成@EmbeddedId注解的复合主键类实例。

    import jakarta.persistence.EmbeddedId;
    import jakarta.persistence.Entity;
    import jakarta.persistence.Table;
    
    @Entity
    @Table(name = "mm_enterprise")
    public class EUID {
        @EmbeddedId
        private EnterprisePK id;
    
        // 你的其他业务字段及对应的getter、setter
        // ...
    }
    
  • 调整Repository接口
    把原来的JpaRepository<EUID, String>改成JpaRepository<EUID, EnterprisePK>,让Repository知道实体的主键类型是复合主键类。

    import org.springframework.data.jpa.repository.JpaRepository;
    
    public interface EUIDRepository extends JpaRepository<EUID, EnterprisePK> {
    }
    

这样调整后,调用findAll()时,Hibernate就能正确识别实体的主键,把查询到的数据库记录正确封装成EUID对象,返回正常的数据列表。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 20:13:27