SQL JPA - 多列作为主键

69

如果我想用多个列来组成一个ID。

SQL示例:

CONSTRAINT [PK_NAME] PRIMARY KEY ([Column1],[Column2],[Column3])
如何使用Jpa实体类来实现这个?通过columndefinition吗?
只需将id字段设置为:
value = Column1 + Column2 + Column3 // aint working.
5个回答

133

你需要为你的复合键创建一个类:

public class CompositeKey implements Serializable {
    private int column1;
    private int column2;
    private int column3;
}

然后在实体类中使用@IdClass注解:

@Entity
@IdClass(CompositeKey.class)
public class EntityExample {
    @Id
    private int column1;
    @Id
    private int column2;
    @Id
    private int column3;
    ...
    ...
}

我认为这应该可以工作。

还有另一个@jklee提到的解决方案。两个都可以,只是个人喜好而已。


5
请注意,有一个要求实现equals / hashCode(请参见https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#identifiers-composite)。 - PresentProgrammer
在这种情况下,EntityExampleRepository extends JpaRepository<EntityExample, ???>会是什么样子? - Prasannjeet Singh
1
@PrasannjeetSingh EntityExampleRepository扩展了JpaRepository<EntityExample, CompositeKey>,你可以查看https://jpa-buddy.com/blog/the-ultimate-guide-on-composite-ids-in-jpa-entities/。 - undefined

28

使用 @Embeddable@EmbeddedId

示例:

@Entity
public class Project implements Serializable {
    @EmbeddedId ProjectId id;
}
 
@Embeddable
class ProjectId implements Serializable {
    int departmentId;
    long projectId;
}

更多信息请点击这里


4
别忘了实现 Serializable 接口 ;-) - Diego Souza

23
如果类中的所有字段都是主键的一部分,那么解决方案将非常简单(扩展@raul-cuth提供的解决方案)。

如果类中所有字段都是主键,则解决方案将很简单(扩展@raul-cuth所提供的解决方案):

@Entity
@IdClass(EntityExample.class)
public class EntityExample implements Serializable {

    @Id
    private int column1;

    @Id
    private int column2;

    @Id
    private int column3;
}

1
如果其中一个字段是外键,怎么办?这将是映射多对多关系表时的典型场景。 - Paulo Merson

4
  1. 使用@Entity类上的@IdClass注释,后跟作为复合主键一部分的各个字段的@Id注释。
  2. 或者可以使用@Embeddable类,其中可以包含复合主键的各个字段,然后可以在@Entity类中使用带有@Embedded注释的此类引用作为属性。 希望这可以帮助你。

2
请注意,Hibernate实体类到SQL DDL脚本生成器将对所有字段进行排序,并且无论其在定义中出现的顺序如何,都将按照这些字段的排序顺序创建表定义以及索引/约束定义。虽然字段在表定义中的出现顺序可能并不重要,但组合索引中字段的顺序确实很重要。因此,您的关键字段必须命名,以便按名称排序时它们按您所需的索引顺序排列。

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