Spring Boot JPA使用@Embeddable复合主键调用save()时报ID类型错误
问题根因
错误提示已经明确说明:CountryLanguages实体的主键类型是CountryLanguagesId,但你在Repository定义、删除操作中都错误使用了Integer作为主键类型。
具体修改步骤
- 修正Repository的泛型定义
JpaRepository的第二个泛型参数为实体主键类型,你需要将ICountryLanguagesJpaRepository的泛型参数从Integer改为CountryLanguagesId:
@Repository public interface ICountryLanguagesJpaRepository extends JpaRepository<CountryLanguages, CountryLanguagesId> { }
- 补全复合主键类的equals、hashCode方法
@Embeddable修饰的复合主键类必须重写equals和hashCode,才能让JPA正确识别主键唯一性,在CountryLanguagesId中添加如下代码:
import java.util.Objects; @Embeddable public class CountryLanguagesId implements Serializable { // 原有代码保持不变 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; CountryLanguagesId that = (CountryLanguagesId) o; return Objects.equals(countryId, that.countryId) && Objects.equals(languageId, that.languageId); } @Override public int hashCode() { return Objects.hash(countryId, languageId); } }
- 修正测试代码中的删除操作
deleteById方法需要传入CountryLanguagesId类型的实例,不能直接传Integer值,修改测试代码里的删除逻辑:
// 替换原来的 repository.deleteById(1); repository.deleteById(new CountryLanguagesId(patu.getCountryId(), patuano.getLanguageId()));
可选优化
- 你的测试方法名
shouldSaveAndRemoveContinents和实际测试的国家语言逻辑不符,可按需修改为更贴合的命名。 - 表中
official字段是boolean类型,实体类中定义为Integer也可以正常映射,但建议改为Boolean类型更贴合字段语义。
内容的提问来源于stack exchange,提问作者Woodsoul
相关产品推荐
相关产品推荐

