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
相关产品推荐
相关产品推荐

