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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 06:04:53  来源:igfitidea点击:

Difference using @Id and @EmbeddedId for a compound key

javahibernate

提问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 Embeddablecompound 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 Idannotation 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 EmbeddedIdand and IdClassannotations 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. If java.util.Dateis 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 EmbeddedIdannotation 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 as Embeddable.

There must be only one EmbeddedIdannotation and no Id annotation when the EmbeddedIdannotation 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 @EmbeddedIdyou can skip annotating the entity class @Embeddablebut with @Idits required.

我参考了 hibernate docs Hiberate 3.5 annotations 参考,其中的区别在于@EmbeddedId您可以跳过对实体类的注释,@Embeddable@Id需要对其进行注释。

I tried using @Idwithout @Embeddableit 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!

我希望这可以帮助别人!