JPA `@EmbeddedId` 和 `@MappedSuperclass` 常见问题:解决“标识符映射列数错误”异常
2024-03-17 14:00:13
## 在 JPA 中使用 @EmbeddedId
和 @MappedSuperclass
时解决“标识符映射列数错误”异常
### 简介
在 JPA 应用程序中,使用 @EmbeddedId
和 @MappedSuperclass
组合来映射嵌入式标识符是一种常见模式。但是,当 @JoinColumns
的顺序与 @EmbeddedId
中列的顺序不匹配时,可能会出现“标识符映射列数错误”异常。
### 问题
当使用 @EmbeddedId
和 @MappedSuperclass
时,如果 @JoinColumns
的顺序与 @EmbeddedId
中列的顺序不匹配,就会出现“标识符映射列数错误”异常。
### 解决方法
要解决此问题,请在 CustomUserType
的 @JoinColumns
中交换 id
和 type
列的顺序。正确的映射应如下所示:
@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
表中的 id
和 type
列。
### 常见问题解答
1. 为什么会发生“标识符映射列数错误”异常?
该异常是由 @JoinColumns
的顺序与 @EmbeddedId
中列的顺序不匹配引起的。
2. 如何解决“标识符映射列数错误”异常?
要解决此异常,请交换 @JoinColumns
中 id
和 type
列的顺序。
3. 除了交换列顺序之外,还有其他方法可以解决此问题吗?
没有其他方法可以解决此问题。
4. 为什么 @JoinColumns
的顺序必须与 @EmbeddedId
中列的顺序相匹配?
这是 JPA 的限制。
5. 使用 @EmbeddedId
和 @MappedSuperclass
时,还有哪些常见错误?
另一个常见错误是忘记在子类中使用 @MapsId
将 @EmbeddedId
的列映射到 @MappedSuperclass
的列。