没有使用@EmbeddedId或@IdClass的超级简单复合键

5

我不知道从什么时候开始,这种方式就成为可能了,但是我刚刚创建了复合键,而且使用了我一直想要的方式:不需要@EmbeddedId@IdClass!!

  • Spring 4.0.0.M3
  • Hibernate 4.3.0.Beta4
  • JPA 2.1

User.java:

@Entity
public class User {
    @Id
    ...

    @OneToMany(mappedBy="user", cascade=CascadeType.ALL, orphanRemoval=true)
    private List<GroupUser> groupUsers;     
}

Group.java:

@Entity
public class Group {
    @Id
    ...

    @OneToMany(mappedBy="user", cascade=CascadeType.ALL, orphanRemoval=true)
    private List<GroupUser> groupUsers;     
}

GroupUser.java:

@Entity
public class GroupUser implements Serializable {
    @Id
    @ManyToOne
    @JoinColumn(name="Group_id")
    private Group group;

    @Id
    @ManyToOne
    @JoinColumn(name="User_id")
    private User user;

    @Id
    @Column
    private String s;

    @Column
    private int i;
}

这是MySQL的说法:

 USER             GROUP_USER            GROUP
------    -------------------------    -------
 id        User_id  (PK, NOT NULL)       id 
           Group_id (PK, NOT NULL)
           s        (PK, NOT NULL)
           i        (DEFAULT NULL)

GROUP_USER 详细信息:

  • 主键:User_id、Group_id、s
  • 索引#1 / 外键:User_id
  • 索引#2 / 外键:Group_id

我还进行了其他测试,例如:

@Entity
public class A implements Serializable {

    @Id
    @Column
    String a;

    @Id
    @Column
    String b;

    @Column
    String c;

}

太棒了!效果很好!


还有使用@EmbeddedId@IdClass的任何理由吗?

这是JPA 2.1的一部分还是Hibernate的一个特性?

1个回答

3

JPA要求为复合主键定义某种主键类。实际上,这似乎主要是为了EntityManager的find和getReference调用所需的pk类实例。实现可能有自己的pk表示,可以用于这些调用,但不具备可移植性。


好的。这听起来像是一个Hibernate的特性。但这一点也不糟糕,该项目严重依赖于JBoss/Hibernate技术。 - Benjamin M
你可能仍然想要定义一个键类,因为它定义了用于查找和获取引用的合同,在实体中明确未来重用。 - Chris
你会使用 @EmbeddedId 还是 @IdClass@IdClass 看起来更简单,有什么缺点吗? - Benjamin M
1
顺便提一下:这是我问题的答案(在2.2.3.2.复合标识符下):http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/#entity-mapping-identifier。文中说道:“将多个属性映射为@Id属性:标识符类型则是实体类本身,需要可序列化。不幸的是,这种方法并不标准,只有Hibernate支持。” - Benjamin M
EmbeddedId基本上是在实体内部缓存pk类实例。在我看来,这是额外的开销/抽象,如果你很少使用它,那么它是不必要的。我相信EclipseLink也允许不定义PK类,而是采用自己的CacheKey表示或者一组pk值作为键。 - Chris
1
我真的无法决定。对我来说,一遍又一遍地定义所引用对象的ID的基础类型似乎毫无意义。太糟糕了,那些JPA的家伙从来没有考虑过简单而有用的解决方案 ;) - Benjamin M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接