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

问题描述 投票:0回答:2

我创建了一个使用

@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
注释有区别吗?

java hibernate
2个回答
31
投票

我实际上很惊讶“之前”版本的工作原理。根据规范,映射

Embeddable
复合键的正确方法是 “after” 版本。引用JPA 1.0规范:

2.1.4 主键和实体身份

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

主键必须定义在 实体是实体的根 层次结构或映射的超类 实体层次结构。主键 必须在一个中恰好定义一次 实体层次结构。

简单(即非复合)初级 key 必须对应一个 的持久字段或属性 实体类。

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
用作 主键字段或属性, 时间类型应指定为 日期。

...

后来:

9.1.14 嵌入式Id注解

应用了

EmbeddedId
注释 的持久字段或属性 实体类或映射超类 表示复合主键 是一个可嵌入的类。可嵌入的 类必须注释为
Embeddable

必须只有一个

EmbeddedId
注释且无 Id 注释时 使用
EmbeddedId
注释。


17
投票

我参考了 hibernate 文档 Hiberate 3.5 注释参考,其中的区别是使用

@EmbeddedId
你可以跳过注释实体类
@Embeddable
但使用
@Id
这是必需的。

我尝试使用

@Id
而不使用
@Embeddable
它给出了异常:

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

仅此而已,没有字段或类名等额外信息。

这个行为是从 Hibernate 4 开始的;我不知道其他 JPA 提供商的情况。如果有更多发现,我将测试一些并相应更新帖子。

© www.soinside.com 2019 - 2024. All rights reserved.