返回

JPA `@EmbeddedId` 和 `@MappedSuperclass` 常见问题:解决“标识符映射列数错误”异常

java

## 在 JPA 中使用 @EmbeddedId@MappedSuperclass 时解决“标识符映射列数错误”异常

### 简介

在 JPA 应用程序中,使用 @EmbeddedId@MappedSuperclass 组合来映射嵌入式标识符是一种常见模式。但是,当 @JoinColumns 的顺序与 @EmbeddedId 中列的顺序不匹配时,可能会出现“标识符映射列数错误”异常。

### 问题

当使用 @EmbeddedId@MappedSuperclass 时,如果 @JoinColumns 的顺序与 @EmbeddedId 中列的顺序不匹配,就会出现“标识符映射列数错误”异常。

### 解决方法

要解决此问题,请在 CustomUserType@JoinColumns 中交换 idtype 列的顺序。正确的映射应如下所示:

@JoinColumns({
    @JoinColumn(name = "type", referencedColumnName = "type", insertable = false, updatable = false),
    @JoinColumn(name = "id", referencedColumnName = "id", insertable = false, updatable = false)
})

### 原因

@EmbeddedId@MappedSuperclass 组合使用的正确方法是,在子类中使用 @MapsId@EmbeddedId 的列映射到 @MappedSuperclass 的列。@JoinColumns 的顺序应与 @EmbeddedId 中列的顺序相匹配。

### 修改后的 DDL

使用修改后的 @JoinColumns,DDL 将如下所示:

CREATE TABLE customer_user_typea (
    typea_field1 VARCHAR(255),
    typea_field2 VARCHAR(255),
    id BIGINT NOT NULL,
    type VARCHAR(255) NOT NULL,
    CONSTRAINT pk_customerusertypea PRIMARY KEY (id)
);
ALTER TABLE customer_user_typea ADD CONSTRAINT FK_CUSTOMERUSERTYPEA_ON_ID FOREIGN KEY (id, type) REFERENCES base_user (id, type);

请注意,外键约束现在正确地引用了 base_user 表中的 idtype 列。

### 常见问题解答

1. 为什么会发生“标识符映射列数错误”异常?

该异常是由 @JoinColumns 的顺序与 @EmbeddedId 中列的顺序不匹配引起的。

2. 如何解决“标识符映射列数错误”异常?

要解决此异常,请交换 @JoinColumnsidtype 列的顺序。

3. 除了交换列顺序之外,还有其他方法可以解决此问题吗?

没有其他方法可以解决此问题。

4. 为什么 @JoinColumns 的顺序必须与 @EmbeddedId 中列的顺序相匹配?

这是 JPA 的限制。

5. 使用 @EmbeddedId@MappedSuperclass 时,还有哪些常见错误?

另一个常见错误是忘记在子类中使用 @MapsId@EmbeddedId 的列映射到 @MappedSuperclass 的列。