我创建了一个使用@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注释有区别吗?
答案 0 :(得分:27)
我真的很惊讶“在”版本工作之前。根据规范,映射Embeddable
复合键的正确方法是“版本之后的”。引用JPA 1.0规范:
2.1.4主键和实体标识
每个实体都必须有一个主键。
必须在主键上定义主键 作为实体根的实体 层次结构或映射的超类 实体层次结构。主键 必须在一个中完全定义一次 实体层次结构。
简单(即非复合)主要 key必须对应一个 持久的领域或财产 实体类。
Id
注释是 用于表示简单的主键。 见9.1.8。复合主键必须 对应于任何一个 持久的领域或财产或 一组这样的字段或属性为 如下面所描述的。主键类 必须定义为代表a 复合主键。综合 主键通常出现在 当遗留数据库映射时 数据库密钥由几个组成 列。
EmbeddedId
和IdClass
注释用于 表示复合主键。看到 第9.1.14和9.1.15节。主键(或字段或属性 一个复合主键)应该是 以下类型之一:任何Java 原始类型;任何原始包装器 类型;
java.lang.String
;java.util.Date
;java.sql.Date
。在 但是,一般是近似数字 类型(例如,浮点类型) 永远不应该在主键中使用。 主键使用类型的实体 除了这些将不可携带。 如果生成主键是 使用过,只有整数类型 便携。如果使用java.util.Date
主键字段或属性, 时间类型应指定为 DATE。...
后来:
9.1.14 EmbeddedId Annotation
应用
EmbeddedId
注释 持久的领域或财产 实体类或映射的超类 表示复合主键 是一个可嵌入的类。嵌入式 class必须注释为Embeddable
。必须只有一个
EmbeddedId
注释和没有Id注释时 使用EmbeddedId
注释。
答案 1 :(得分:13)
这个答案为时已晚,但万一有所帮助。
我提到了hibernate docs Hiberate 3.5 annotations reference,其中与@EmbeddedId
不同的是,您可以跳过注释实体类@Embeddable
但需要@Id
。
我尝试使用@Id
而没有@Embeddable
它会出现异常:
org.hibernate.mapping.SimpleValue无法强制转换为org.hibernate.mapping.Component
就是这个,没有像字段或类名这样的额外信息。
这个行为就像Hibernate 4一样;我不知道其他JPA提供商。如果有更多的发现,我会测试一些并相应地更新帖子。
我希望这有助于某人!