JPA使用LEFT JOIN FETCH查询时PSQLException类型不匹配错误如何解决?
问题根因分析与修复方案
核心问题
你遇到的类型不匹配报错是两个原因共同导致的:
- 嵌入式主键字段映射不匹配:
FooId类中id属性的@Column注解指定的列名为fooId,但数据库表foo_definition的主键实际字段名为foo_id,Hibernate生成SQL时字段映射错误,误将其他数值类型字段作为匹配条件,因此出现bigint和varchar无法比较的报错。 - 主键类缺少必要方法:
@Embeddable修饰的复合主键类必须重写equals和hashCode方法,否则Hibernate无法正确完成主键值的匹配逻辑。
修复步骤
第一步:修正嵌入式主键类的配置
@Embeddable @Setter @Getter @NoArgsConstructor @AllArgsConstructor public class FooId implements Serializable { // 列名和数据库实际字段保持一致 @Column(name = "foo_id") private String id; @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; FooId fooId = (FooId) o; return Objects.equals(id, fooId.id); } @Override public int hashCode() { return Objects.hash(id); } }
如果你的项目已经配置了Hibernate自动驼峰转下划线的命名策略,也可以不用修改@Column的name属性,显式指定和数据库一致是兼容性最好的方案
第二步:修正Repository查询方法,以下两种写法二选一即可
写法1:传入FooId实例直接匹配主键
@Query("SELECT c FROM FooDefinition c LEFT JOIN FETCH c.bundles WHERE c.fooId = :fooId") FooDefinition findByIdAndFetchBundlesEagerly(@Param("fooId") FooId fooId);
写法2:传入String类型的id值匹配主键内部属性
@Query("SELECT c FROM FooDefinition c LEFT JOIN FETCH c.bundles WHERE c.fooId.id = :fooId") FooDefinition findByIdAndFetchBundlesEagerly(@Param("fooId") String fooId);
内容的提问来源于stack exchange,提问作者mr nooby noob
相关产品推荐
相关产品推荐

