使用@Id和@EmbeddedId作为复合键的区别

我创建了一个使用@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主键和实体标识

每个实体都必须有一个主键。

必须在作为实体层次结构的根的实体或实体层次结构的映射超类上定义主键。 主键必须在实体层次结构中只定义一次。

简单(即非复合)主键必须对应于实体类的单个持久字段或属性。 Id注释用于表示简单的主键。 见9.1.8节。

复合主键必须对应于单个持久字段或属性,或者对应于下面描述的一组此类字段或属性。 必须定义主键类以表示复合主键。 当数据库密钥由多个列组成时,通常在从旧数据库映射时出现复合主键。 EmbeddedIdIdClass注释用于表示复合主键。 见9.1.14和9.1.15。

主键(或复合主键的字段或属性)应为以下类型之一:任何Java基本类型; 任何原始包装类型; java.lang.String ; java.util.Date ; java.sql.Date 。 但是,通常,不应在主键中使用近似数字类型(例如,浮点类型)。 主键使用其他类型的实体将不可移植。 如果使用生成的主键,则只有整数类型才是可移植的。 如果将java.util.Date用作主键字段或属性,则应将时间类型指定为DATE。

然后:

9.1.14 EmbeddedId注释

EmbeddedId注释应用于实体类或映射超类的持久字段或属性,以表示作为可嵌入类的复合主键。 可嵌入类必须注释为Embeddable

使用EmbeddedId注释时,必须只有一个EmbeddedId注释且没有Id注释。

这个答案为时已晚,但万一有所帮助。

我提到了hibernate docs Hiberate 3.5注释引用 ,其中与@EmbeddedId的区别在于你可以跳过注释实体类@Embeddable但是@Id是必需的。

我尝试使用没有@Embeddable @Id它给出了exception:

org.hibernate.mapping.SimpleValue无法强制转换为org.hibernate.mapping.Component

就是这个,没有像字段或类名这样的额外信息。

那么这个行为就像Hibernate 4一样; 我不知道其他JPA提供商。 如果有更多的发现,我会测试一些并相应地更新post。

我希望这可以帮助别人!