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

时间:2010-10-05 23:26:19

标签: java hibernate

我创建了一个使用@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注释有区别吗?

2 个答案:

答案 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提供商。如果有更多的发现,我会测试一些并相应地更新帖子。

我希望这有助于某人!