简体   繁体   English

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

[英]Difference using @Id and @EmbeddedId for a compound key

I've created an entity that uses @Id to point to an @Embeddable compound key. 我创建了一个使用@Id指向@Embeddable复合键的实体。 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切换到@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注释之间有区别吗?

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. 根据规范,映射Embeddable复合键的正确方法是“after”版本。 Quoting the JPA 1.0 specification: 引用JPA 1.0规范:

2.1.4 Primary Keys and Entity Identity 2.1.4主键和实体标识

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 (ie, 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. Id注释用于表示简单的主键。 See section 9.1.8. 见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 and IdClass annotations are used to denote composite primary keys. EmbeddedIdIdClass注释用于表示复合主键。 See sections 9.1.14 and 9.1.15. 见9.1.14和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; 主键(或复合主键的字段或属性)应为以下类型之一:任何Java基本类型; any primitive wrapper type; 任何原始包装类型; java.lang.String ; java.lang.String ; java.util.Date ; java.util.Date ; java.sql.Date . java.sql.Date In general, however, approximate numeric types (eg, 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.Date is used as a primary key field or property, the temporal type should be specified as DATE. 如果将java.util.Date用作主键字段或属性,则应将时间类型指定为DATE。

... ...

And later: 然后:

9.1.14 EmbeddedId Annotation 9.1.14 EmbeddedId注释

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. EmbeddedId注释应用于实体类或映射超类的持久字段或属性,以表示作为可嵌入类的复合主键。 The embeddable class must be annotated as Embeddable . 可嵌入类必须注释为Embeddable

There must be only one EmbeddedId annotation and no Id annotation when the EmbeddedId annotation is used. 这里必须只有一个EmbeddedId的注释时,没有标识标注EmbeddedId使用注解。

It's too late for this answer but in case it helps. 这个答案为时已晚,但万一有所帮助。

I referred hibernate docs Hiberate 3.5 annotations reference whereby 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注释引用 ,其中与@EmbeddedId的区别在于你可以跳过注释实体类@Embeddable但是需要使用@Id

I tried using @Id without @Embeddable it gives exception: 我尝试使用没有@Embeddable @Id它给出了异常:

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; 那么这个行为就像Hibernate 4一样; I dont know about other JPA providers. 我不知道其他JPA提供商。 I will test a few and update post accordingly if there are any more findings. 如果有更多的发现,我会测试一些并相应地更新帖子。

I hope this helps someone! 我希望这可以帮助别人!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM