我创建了一个使用
@Id
指向 @Embeddable
复合键的实体。 我相信一切都按原样运行良好。 然而,在将 @Id
切换到 @EmbeddedId
后,据我所知,一切都继续正常工作。
之前:
@Entity
public final class MyEntity {
private CompoundKey id;
@Id
public CompoundKey getId() {
return id;
}
public void setId(CompoundKey id) {
this.id = id;
}
之后:
@Entity
public final class MyEntity {
private CompoundKey id;
@EmbeddedId
public CompoundKey getId() {
return id;
}
public void setId(CompoundKey id) {
this.id = id;
}
引用复合键时使用
@Id
和 @EmbeddedId
注释有区别吗?
我实际上很惊讶“之前”版本的工作原理。根据规范,映射
Embeddable
复合键的正确方法是 “after” 版本。引用JPA 1.0规范:
2.1.4 主键和实体身份
每个实体都必须有一个主键。
主键必须定义在 实体是实体的根 层次结构或映射的超类 实体层次结构。主键 必须在一个中恰好定义一次 实体层次结构。
简单(即非复合)初级 key 必须对应一个 的持久字段或属性 实体类。
注释是 用于表示简单的主键。 请参阅第 9.1.8 节。Id
复合主键必须 对应于单个 持久字段或属性或 此类字段或属性的集合 如下所述。主键类 必须定义为代表一个 复合主键。合成的 主键通常出现在以下情况 当从遗留数据库映射 数据库密钥由几个组成 列。
和 和EmbeddedId
注释用于 表示复合主键。看 第 9.1.14 和 9.1.15 节。IdClass
主键(或字段或属性 复合主键)应该是 以下类型之一:任何 Java 原始类型;任何原始包装器 类型;
;java.lang.String
;java.util.Date
。在 一般,但是,近似数字 类型(例如浮点类型) 永远不应该在主键中使用。 主键使用类型的实体 除此之外的其他内容将不可移植。 如果生成的主键是 使用时,只有整型会被使用 便携的。如果java.sql.Date
用作 主键字段或属性, 时间类型应指定为 日期。java.util.Date
...
后来:
9.1.14 嵌入式Id注解
应用了
注释 的持久字段或属性 实体类或映射超类 表示复合主键 是一个可嵌入的类。可嵌入的 类必须注释为EmbeddedId
。Embeddable
必须只有一个
注释且无 Id 注释时 使用EmbeddedId
注释。EmbeddedId
我参考了 hibernate 文档 Hiberate 3.5 注释参考,其中的区别是使用
@EmbeddedId
你可以跳过注释实体类 @Embeddable
但使用 @Id
这是必需的。
我尝试使用
@Id
而不使用 @Embeddable
它给出了异常:
org.hibernate.mapping.SimpleValue 无法转换为 org.hibernate.mapping.Component
仅此而已,没有字段或类名等额外信息。
这个行为是从 Hibernate 4 开始的;我不知道其他 JPA 提供商的情况。如果有更多发现,我将测试一些并相应更新帖子。