当前位置:  开发笔记 > 编程语言 > 正文

我应该使用哪个注释:@IdClass或@EmbeddedId

如何解决《我应该使用哪个注释:@IdClass或@EmbeddedId》经验,为你挑选了5个好方法。

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

我在我的映射实体上使用了两个注释,但对于那些不熟悉的人来说,结果却是一团糟JPA.

我想只采用一种方法来指定复合键.哪一个真的最好?为什么?



1> Jorge Ferrei..:

我认为这@EmbeddedId可能更冗长,因为@IdClass您无法使用任何字段访问运算符访问整个主键对象.使用@EmbeddedId你可以这样做:

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

这给出了构成组合键的字段的清晰概念,因为它们都是在通过字段访问操作符访问的类中聚合的.

与另一个不同之处@IdClass,并@EmbeddedId是当它涉及到写HQL:

@IdClass你写:

select e.name from Employee e

@EmbeddedId你一起写:

select e.employeeId.name from Employee e

您必须为同一查询编写更多文本.有些人可能会认为这与一种更自然的语言不同,例如推广的语言IdClass.但是大多数时候从查询中理解给定字段是复合键的一部分是非常宝贵的帮助.


虽然我同意上面给出的解释,但我还想为`@ IdClass`添加一个独特的用例,尽管在大多数情况下我更喜欢`@ EmbeddedId`(在Antonio Goncalves的会话中了解这一点.他建议的是如果复合键类不可访问,或者来自另一个我们无法添加注释的模块或遗留代码,我们可以使用`@ IdClass`.在这些场景中,`@ IdClass`将为我们提供一种方式.

2> laz..:

我发现了一个必须使用EmbeddedId而不是IdClass的实例.在这种情况下,有一个连接表,其中定义了其他列.我尝试使用IdClass来解决此问题,以表示明确表示连接表中的行的实体的键.我无法以这种方式工作.值得庆幸的是"Java Persistence With Hibernate"有一节专门讨论这个主题.一个提议的解决方案与我的解决方案非常相似,但它使用的是EmbeddedId.我在书中的对象之后对我的对象进行了建模,现在它的行为正确.



3> Adelin..:

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

将其标记为@Embeddable并为您的实体类添加标准属性,标记为@Id.

添加到您的实体类的标准属性,标记为@EmbeddedId.

在实体类中为其所有字段添加属性,标记它们@Id,并用@IdClass实际类标记,提供主键类的类.

@Id标记为类的使用@Embeddable是最自然的方法.@Embeddable无论如何,该标记可用于非主键可嵌入值.它允许您将复合主键视为单个属性,并允许@Embeddable在其他表中重用该类.

下一个最自然的方法是使用@EmbeddedId标签.这里,主键类不能在其他表中使用,因为它不是@Embeddable实体,但它确实允许我们将键视为某个类的单个属性.

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

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



4> Ondrej Bozek..:

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

随着@EmbeddedId你必须定义映射为您的FK列两次,onece在@Embeddedable一次用于为即@ManyToOne其中@ManyToOne已经被只读(@PrimaryKeyJoinColumn),因为你不能有一列两个变量(可能发生的冲突)设置.
所以你必须使用简单的类型来设置你的FK @Embeddedable.

在使用@IdClass这种情况的另一个站点上可以更容易地处理,如主键通过OneToOne和ManyToOne关系所示:

示例JPA 2.0 ManyToOne id注释

...
@Entity
@IdClass(PhonePK.class)
public class Phone {

    @Id
    private String type;

    @ManyToOne
    @Id
    @JoinColumn(name="OWNER_ID", referencedColumnName="EMP_ID")
    private Employee owner;
    ...
}

示例JPA 2.0 id类

...
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> bertie..:

我认为主要优点是我们可以在使用@GeneratedValue时使用id @IdClass?我敢肯定,我们不能用@GeneratedValue@EmbeddedId.

推荐阅读
吻过彩虹的脸_378
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有