代码之家  ›  专栏  ›  技术社区  ›  sakana

我应该使用哪种注释:@IdClass还是@EmbeddedId

  •  110
  • sakana  · 技术社区  · 16 年前

    JPA (Java持久性API)规范有两种不同的方法来指定实体组合键: @IdClass @EmbeddedId .

    我在映射的实体上使用了这两种注释,但对于不太熟悉它们的人来说,结果是一团混乱 JPA

    7 回复  |  直到 9 年前
        1
  •  104
  •   Kurt Du Bois    10 年前

    我认为 @EmbeddedId @IdClass 不能使用任何字段访问操作符访问整个主键对象。使用 @嵌入ID 您可以这样做:

    @Embeddable class EmployeeId { name, dataOfBirth }
    @Entity class Employee {
      @EmbeddedId EmployeeId employeeId;
      ...
    }
    

    另一个不同点是 @嵌入ID 在编写HQL时:

    @IdClass 你写道:

    select e.name from Employee e

    你必须写:

    select e.employeeId.name from Employee e

    您必须为同一查询编写更多文本。有些人可能会争辩说,这不同于一种更为自然的语言,如 IdClass

        2
  •  22
  •   Martin    7 年前

    使用复合主键有三种策略:

    • 标记为 @Embeddable 并为实体类添加一个普通属性,标记为 @Id .
    • 为实体类添加一个普通属性,标记为 @EmbeddedId .
    • 为实体类的所有字段添加属性,并用 @IdClass ,提供主键类的类。

    @身份证 将一个类标记为 @可嵌入 这是最自然的方法。这个 标记可用于非主键可嵌入值。它允许您将复合主键视为单个属性,并允许重用 @可嵌入 在其他表格中输入。

    第二个最自然的方法是使用 标签在这里,主键类不能在其他表中使用,因为它不是 @可嵌入 某个类的单个属性。

    最后,使用 @IdClass 注释允许我们使用与主键类中属性名称对应的实体本身的属性映射复合主键类。名称必须对应(没有覆盖该名称的机制),主键类必须履行与其他两种技术相同的义务。这种方法的唯一优点是能够从封闭实体的接口隐藏主键类的使用。这个 @IdClass 注释采用类类型的值参数,该参数必须是用作复合主键的类。与要使用的主键类的属性相对应的字段都必须用 @身份证 .

    参考: http://www.apress.com/us/book/9781430228509

        3
  •  17
  •   laz    10 年前

    我发现了一个必须使用EmbeddedId而不是IdClass的实例。在此场景中,有一个定义了附加列的联接表。我试图使用IdClass来表示显式表示联接表中的行的实体的键来解决这个问题。我不能让它这样工作。谢天谢地,“带Hibernate的Java持久性”有一节专门讨论这个主题。一个提议的解决方案与我的非常相似,但它使用了EmbeddedId。我按照书中的对象建模,现在它的行为正常了。

        4
  •  13
  •   Emil Sierżęga Awanish Prakash    7 年前

    据我所知,如果你的复合PK包含FK,那么使用起来就更简单、更直接 @IdClass

    具有 @EmbeddedId @Embeddedable 一次作为,也就是说。 @ManyToOne 哪里 @PrimaryKeyJoinColumn )因为不能在两个变量中设置一列(可能存在冲突)。
    因此,您必须使用简单的输入设置FK

    在另一个站点上使用 如中所示,可以更轻松地处理这种情况 Primary Keys through OneToOne and ManyToOne Relationships :

    ...
    @Entity
    @IdClass(PhonePK.class)
    public class Phone {
    
        @Id
        private String type;
    
        @ManyToOne
        @Id
        @JoinColumn(name="OWNER_ID", referencedColumnName="EMP_ID")
        private Employee owner;
        ...
    }
    

    JPA2.0ID类示例

    ...
    public class PhonePK {
        private String type;
        private long owner;
    
        public PhonePK() {}
    
        public PhonePK(String type, long owner) {
            this.type = type;
            this.owner = owner;
        }
    
        public boolean equals(Object object) {
            if (object instanceof PhonePK) {
                PhonePK pk = (PhonePK)object;
                return type.equals(pk.type) && owner == pk.owner;
            } else {
                return false;
            }
        }
    
        public int hashCode() {
            return type.hashCode() + owner;
        }
    }
    
        5
  •  8
  •   bluish dmajkic    10 年前

    我认为主要的优势是我们可以利用 @GeneratedValue 用于在使用 @IdClass ? 我肯定我们不能用 @生成值 对于 @EmbeddedId

        6
  •  5
  •   bluish dmajkic    10 年前

    复合密钥不能有 @Id 财产何时 @EmbeddedId 使用。

        7
  •  1
  •   Aleks Ben Maza    6 年前

    使用EmbeddedId,您可以在HQL中使用IN子句,例如: FROM Entity WHERE id IN :ids FROM Entity WHERE idPartA = :idPartA0 AND idPartB = :idPartB0 .... OR idPartA = :idPartAN AND idPartB = :idPartBN