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

添加双向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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 17:52:47