Java 使用 @Id 和 @EmbeddedId 作为复合键的区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3868515/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Difference using @Id and @EmbeddedId for a compound key
提问by digiarnie
I've created an entity that uses @Id to point to an @Embeddable compound key. Everything I believe works fine as is. However, after switching @Id to @EmbeddedId everything continues to work fine as far as I can tell.
我创建了一个使用@Id 指向@Embeddable 复合键的实体。我认为一切正常。但是,在将 @Id 切换为 @EmbeddedId 之后,据我所知,一切都继续正常工作。
Before:
前:
@Entity
public final class MyEntity {
private CompoundKey id;
@Id
public CompoundKey getId() {
return id;
}
public void setId(CompoundKey id) {
this.id = id;
}
After:
后:
@Entity
public final class MyEntity {
private CompoundKey id;
@EmbeddedId
public CompoundKey getId() {
return id;
}
public void setId(CompoundKey id) {
this.id = id;
}
Is there a difference between using the @Id and @EmbeddedId annotations when referencing a compound key?
引用复合键时,使用 @Id 和 @EmbeddedId 注释有区别吗?
采纳答案by Pascal Thivent
I'm actually surprised the "before"version is working. According to the specification, the correct way to map your Embeddable
compound key is the "after"version. Quoting the JPA 1.0 specification:
我实际上很惊讶“之前”版本的工作。根据规范,映射Embeddable
复合键的正确方法是“之后”版本。引用 JPA 1.0 规范:
2.1.4 Primary Keys and Entity Identity
Every entity must have a primary key.
The primary key must be defined on the entity that is the root of the entity hierarchy or on a mapped superclass of the entity hierarchy. The primary key must be defined exactly once in an entity hierarchy.
A simple (i.e., non-composite) primary key must correspond to a single persistent field or property of the entity class. The
Id
annotation is used to denote a simple primary key.See section 9.1.8.A composite primary key must correspond to either a single persistent field or property or to a set of such fields or properties as described below. A primary key class must be defined to represent a composite primary key. Composite primary keys typically arise when mapping from legacy databases when the database key is comprised of several columns. The
EmbeddedId
and andIdClass
annotations are used to denote composite primary keys. See sections 9.1.14 and 9.1.15.The primary key (or field or property of a composite primary key) should be one of the following types: any Java primitive type; any primitive wrapper type;
java.lang.String
;java.util.Date
;java.sql.Date
. In general, however, approximate numeric types (e.g., floating point types) should never be used in primary keys. Entities whose primary keys use types other than these will not be portable. If generated primary keys are used, only integral types will be portable. Ifjava.util.Date
is used as a primary key field or property, the temporal type should be specified as DATE....
2.1.4 主键和实体身份
每个实体都必须有一个主键。
必须在作为实体层次结构根的实体或实体层次结构的映射超类上定义主键。主键必须在实体层次结构中只定义一次。
一个简单的(即非复合的)主键必须对应于实体类的单个持久字段或属性。该
Id
注释被用来表示一个简单的主键。见第 9.1.8 节。复合主键必须对应于单个持久字段或属性,或者对应于如下所述的一组此类字段或属性。必须定义主键类来表示复合主键。当数据库键由多个列组成时,从旧数据库映射时通常会出现复合主键。的
EmbeddedId
和和IdClass
注解用于表示复合主键。见 9.1.14 和 9.1.15 节。主键(或复合主键的字段或属性)应该是以下类型之一:任何 Java 原始类型;任何原始包装类型;
java.lang.String
;java.util.Date
;java.sql.Date
. 然而,一般来说,近似数字类型(例如,浮点类型)不应在主键中使用。主键使用除这些类型以外的类型的实体将不可移植。如果使用生成的主键,则只有整数类型是可移植的。如果java.util.Date
用作主键字段或属性,则应将时间类型指定为 DATE。...
And later:
然后:
9.1.14 EmbeddedId Annotation
The
EmbeddedId
annotation is applied to a persistent field or property of an entity class or mapped superclass to denote a composite primary key that is an embeddable class. The embeddable class must be annotated asEmbeddable
.There must be only one
EmbeddedId
annotation and no Id annotation when theEmbeddedId
annotation is used.
9.1.14 EmbeddedId 注解
该
EmbeddedId
注释被施加到一个实体类的持久字段或属性或映射超表示一个复合主密钥是一个可嵌入类。可嵌入类必须注释为Embeddable
.使用
EmbeddedId
注解时必须只有一个注解,不能有Id注解EmbeddedId
。
回答by baba.kabira
It's too late for this answer but in case it helps.
这个答案为时已晚,但以防万一。
I referred hibernate docs Hiberate 3.5 annotations referencewhereby there is the difference that with @EmbeddedId
you can skip annotating the entity class @Embeddable
but with @Id
its required.
我参考了 hibernate docs Hiberate 3.5 annotations 参考,其中的区别在于@EmbeddedId
您可以跳过对实体类的注释,@Embeddable
但@Id
需要对其进行注释。
I tried using @Id
without @Embeddable
it gives exception:
我尝试在@Id
没有@Embeddable
它的情况下使用会出现异常:
org.hibernate.mapping.SimpleValue cannot be cast to org.hibernate.mapping.Component
org.hibernate.mapping.SimpleValue 不能转换为 org.hibernate.mapping.Component
Just this and no extra info like the field or class name.
只是这个,没有像字段或类名这样的额外信息。
Well this behavior is as of Hibernate 4; I dont know about other JPA providers. I will test a few and update post accordingly if there are any more findings.
好吧,这种行为从 Hibernate 4 开始;我不知道其他 JPA 提供商。如果有更多发现,我将测试一些并相应地更新帖子。
I hope this helps someone!
我希望这可以帮助别人!