添加双向ManyToMany关联时出现Could not determine recommended JdbcType错误求助
问题原因与修复方案
错误原因
你的project_supplier关联表并非标准的多对多关联表——它包含了id(自增主键)、notes、daily_rate这些额外字段,而JPA的@ManyToMany注解仅适用于仅包含两个外键的纯关联表。当你添加双向@ManyToMany关联时,Hibernate无法处理带额外字段的关联表结构,导致无法推断Project实体对应的JDBC类型,从而抛出异常。
修复方案
需要将多对多关联拆分为两个一对多关联,通过创建中间实体来映射project_supplier表的所有字段。具体步骤如下:
1. 创建中间实体ProjectSupplier
该实体直接映射关联表的所有字段,并与Project、Supplier建立多对一关联:
@Entity @Table(name = "project_supplier") public class ProjectSupplier { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "project_id", nullable = false) private Project project; @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "supplier_id", nullable = false) private Supplier supplier; private String notes; @Column(name = "daily_rate", nullable = false) private BigDecimal dailyRate; // 重写equals和hashCode,避免重复关联(基于关联的Project和Supplier主键) @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ProjectSupplier that = (ProjectSupplier) o; return Objects.equals(project.getId(), that.project.getId()) && Objects.equals(supplier.getId(), that.supplier.getId()); } @Override public int hashCode() { return Objects.hash(project.getId(), supplier.getId()); } // getter、setter方法 }
2. 修改Project实体
将原有的Set<Supplier>替换为Set<ProjectSupplier>,并建立一对多关联:
@Entity @Table(name = "project") public class Project { // 基础属性略 @OneToMany(mappedBy = "project", cascade = CascadeType.ALL, orphanRemoval = true) private Set<ProjectSupplier> projectSuppliers = new HashSet<>(); // 可选:添加辅助方法简化关联操作 public void addSupplier(Supplier supplier, BigDecimal dailyRate, String notes) { ProjectSupplier projectSupplier = new ProjectSupplier(); projectSupplier.setProject(this); projectSupplier.setSupplier(supplier); projectSupplier.setDailyRate(dailyRate); projectSupplier.setNotes(notes); this.projectSuppliers.add(projectSupplier); supplier.getProjectSuppliers().add(projectSupplier); } // getter、setter方法 }
3. 修改Supplier实体
同样替换关联字段为Set<ProjectSupplier>,建立一对多关联:
@Entity @Table(name = "supplier") public class Supplier { // 基础属性略 @OneToMany(mappedBy = "supplier", cascade = CascadeType.ALL, orphanRemoval = true) private Set<ProjectSupplier> projectSuppliers = new HashSet<>(); // getter、setter方法 }
说明
这种方式本质上是把带额外属性的关联表当作独立实体处理,通过中间实体维护Project与Supplier的关联关系,同时保留关联表中的额外字段数据,符合你的数据库结构需求。
内容的提问来源于stack exchange,提问作者AndreaNobili
相关产品推荐
相关产品推荐

