JPA ManyToMany报错'must have same number of columns as the referenced primary key'解决
问题背景
我有三张表:customer、product,还有用于存储客户购买商品记录的关联表sales,实体类定义如下:
Customer.java
@Entity @Table(name="customer") public class Customer { @Id @Column(name="c_id") private String customerId; @Column(name="customer_name") private String customerName; @ManyToMany @JoinTable( name = "sale", joinColumns = @JoinColumn(name = "c_id"), inverseJoinColumns = @JoinColumn(name = "p_id")) private Set<Product> customerProducts = new HashSet<>(); }
Product.java
@Entity @Table(name="product") public class Product { @Id @Column(name="p_id") private String productId; @Column(name="product_name") private String productName; @Column(name="price") private Double price; // ... Setters & Getters }
Sales.java
@Entity @Table(name="sales") public class Sales { @EmbeddedId private SalesPK salesId; @Column(name="qty") private Long qty; // ... Setters & Getters }
SalesPK.java
@Embeddable public class SalesPK implements Serializable { @Column(name = "c_id") private String customerId; @Column(name = "p_id") private String productId; public SalesPK() {} public SalesPK(String customerId, String productId) { this.customerId = customerId; this.productId = productId; } }
CustomerRepository.java
@Repository public interface CustomerRepository extends CrudRepository<Customer, String> { @Query("select customer from Customer customer " + "left join fetch customer.customerProducts " + "where customer.customerName = :customerName") public Customer getCustomerPurchasedProducts(String customerName); }
Spring Boot应用启动失败,抛出如下异常:
org.hibernate.MappingException: Foreign key (FK7wwx8x75009xqb1y0tawm8rty:SALES [p_id])) must have same number of columns as the referenced primary key (SALES [c_id,p_id])
错误原因
配置中Customer类的@ManyToMany注解关联的@JoinTable表名填写错误,实际关联表名为sales,但配置里写的是sale。
Hibernate找不到名为sale的表时,会尝试基于现有映射匹配关联关系,错误匹配到了带复合主键的sales表结构,因此抛出外键列数和主键列数不匹配的异常,而非直接提示表不存在。
修复方案
将@JoinTable的name属性值改为正确的关联表名sales即可,修复后的代码如下:
@ManyToMany @JoinTable( name = "sales", joinColumns = @JoinColumn(name = "c_id"), inverseJoinColumns = @JoinColumn(name = "p_id")) private Set<Product> customerProducts = new HashSet<>(); }
内容的提问来源于stack exchange,提问作者softechie
相关产品推荐
相关产品推荐

